Come ottimizzare un loop?

lunedì 02 giugno 2008 - 12.34

paquito_ita Profilo | Senior Member

Ciao,

devo creare una descrizione di un sito web usando SIOC (web semantico) usando C#. In particolare la struttura prevede diversi spazi (projects) ognuno con una root folder che contiene documenti e/o cartelle figlie.

I dati sensibili risiedono su un DB MS SQL server e per estrarli uso il seguente approccio (ricercando la max generalità ed evitando di usare statement di SQL Server):

1) Eseguo UNA sola query sulla table FOLDER per ottenere ogni cartella con i relativi dati, l'ID e quello della cartella padre (rootfolder ha ParentID = 0) e UNA query anche per la table DOCS per estrarre i dati sui documenti, in particolare FolderID indica a quale crtella appartiene il documento.

2) Creo tanti oggetti "FOLDER" quanti sono i dati restituiti dalla prima query e li inserisco in un vector (Vector<Folder>) che andrà come VALUE in una HashTable dove la KEY è Folder.ParentID. In tal modo per ogni FolderID avro', raggruppati in un unico Vector, tutte le cartelle figlio.

3) Estraggo quindi (per ogni progetto) dalla HashTable la cartella root e invoco il metodo ricorsivo appendChild:
public static void appendChild(int ID, Resource RES) { Vector<Folder> currFold = table.get(ID); for(int i=0; i<currFold.size(); i++) { //Extract the child and crate the relative resource if(table.containsKey(currFold[i].getID())) { appendChild(currFold[i].getID(), Resource newRES); } } }

In tal modo esploro in profondità la struttura gerarchica delle cartelle usando un approccio "left most". Tale procedimento dovrebbe essere fatto per una struttura di cartelle con 4 livelli di profondità (in media circa 30 cartelle in totale) contenenti documenti e che rappresenta la documents library di un progetto. Tale procedimento di descrizione della documents library va ripetuto per ogni progetto (circa 20 in totale).
Ad ogni modo dopo avere popoato la HashTable per ogni progetto ed usato il relativo contenuto eseguo il flush() dato che nn mi serve mantenerne poi il contenuto, visto che lo uso per creare dinamicamente "risorse" nell'ambito degli statement SIOC. Userei quindi solo una HashTable che ogni volta viene popolata e svuotata.

Vi pare che tale approccio sia valido oppure me ne consigliate un altro che sia piu' performante?
Cercando sempre di adottare una soluzione generale che non si appoggi a istruzioni specifiche di un database.

Grazie!

19018 Profilo | Expert

Sinceramente non ho capito molto :)

Però ti posso dare un suggerimento generale, dopo valuta tu se è possibile usarlo nel tuo caso.
Dovresti cercare di scomporre il problema in più sottoproblemi (meglio se indipendenti) e poi usare un pool di thread assegnando ad ogni thread un sottoproblema.

Per spiegarti con un esempio :

Se devo visitare un albero binario per cercare un particolare valore allora divido l'albero in due ed assegno la ricerca a due thread diversi che girano in "parallelo" . Questo caso mi è capitato svariate volte e usando questo meccanismo ho ottenuto notevoli miglioramenti.
Logicamente più è complesso l'algoritmo e più sentirai la differenza. Magari nel tuo caso non vedrai differenza.
Di sicuro se usi .Net Parallel le prestazioni schizzano ed il parallelismo (se usi più core) è garantito non è finto come in un uniprocessor.

ciao
Stefano Passatordi

http://blogs.dotnethell.it/stem/

paquito_ita Profilo | Senior Member

Cia Stefano,

>Sinceramente non ho capito molto :)
Non posso darti torto. Cerco di chiarire meglio.

La struttura che devo considerare è la seguente:

PROGETTO
|
|-------Root_Folder
| |
| |----Fold_Child1
| |----Fold_Child2
| |--------Doc1
|-------SubProject_A
|
|---Root_Folder
| |----Fold_Child1
| | |----Doc2
| |----Fold_Child2
| |
| |----Doc3
|---SubProjectB
|
|---Root_Folder

Ogni progetto (principale o sottoprogetto) ha una cartella di root dove sono contenuti documenti o altre cartelle figlio e puo' contenere altri sotto progetti.

Questa è la struttura per ogni progetto che devo "descrivere" il semantic web. Dovendo creare ed aggiungere relazioni fra ogni elemento ed i relativi padri/figli (cioè per ogni elemento devo dire: A è mio padre e B è mio figlio, creando relazioni) ho pensato di mettere TUTTI gli elementi di nteresse per ogni progetto in HashTable e poterli cosi' prelevare come voglio io.

>Dovresti cercare di scomporre il problema in più sottoproblemi
>(meglio se indipendenti) e poi usare un pool di thread assegnando
>ad ogni thread un sottoproblema.

Inizialmente avevo anche pensato a diversi Thread, ma nn l'ho mai fatto in C# e .NET quindi mi sn totalmente ignari eventuali classi/metodi appositi. Come faccio a separare una struttura di questo genere in due?

Grazie di nuovo.

19018 Profilo | Expert

La divisione per 2 era solo un esempio.
Ad ogni root potresti assegnare un thread ad esempio.
Devi vedere System.Threading per la gestione dei threads.
ciao
Stefano Passatordi

http://blogs.dotnethell.it/stem/
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5