2012-02-16 13 views
5

Non posso fare a meno di chiedermi se gli spazi dei nomi o la struttura della cartella del progetto influenzano le prestazioni dell'assieme. Il mio istinto dice "" no, ma potrebbe avere effetto sul tempo di compilazione ".Lo spazio dei nomi o la struttura delle cartelle influiscono sulle prestazioni di un assieme?

Pensare alla performance è sempre d'intralcio, soprattutto se sei un principiante. Non posso farci niente! Quindi, pensavo di chiedere ai miei colleghi sviluppatori di giochi che rispetto e ammiro.

+0

Non voglio competere con la risposta di @PlayDeezGames: davvero non lo sarà. Nei linguaggi dinamici può. In SQL Server può colpire fino al 30% di costi. Mai in C#. –

risposta

17

Ognuno ha spiegato come l'ottimizzazione prematura è una cattiva idea (che è): tuttavia spiegherò perché in realtà non fa alcuna differenza (eccetto per i casi in cui si usa la riflessione - ne riparleremo più avanti).

riferimento statico Nel Codice

Il CLR (e quindi MSIL - che è ciò che C# compila a) ha in realtà alcuna nozione o concetto di spazi dei nomi. Un tipo (classe, enum, ecc.) Viene indicato con il suo nome completo (ad esempio System.Runtime.Serialization.ISerializable) e "punti fermi" sono altrettanto opachi (significativi) come qualsiasi altro carattere nel nome. L'intero concetto di namespace è qualcosa che C# (o qualsiasi altra lingua tu stia usando) ti fornisce. Tuttavia, in termini di MSIL raw, il nome del tipo in realtà non importa.

In MSIL non si fa mai riferimento a qualcosa con il suo nome. Tutto in un assembly (dll o exe) ha un certo tipo di handle. Ad esempio, un tipo ha uno TypeHandle e tutto ciò che è contenuto in un tipo ha un MemberHandle: entrambi sono numeri interi a 32 bit. Quindi quando chiami un metodo non scrivi call <MethodName> on <TypeName> in <Assembly> in MSIL - invece scrivi call <MethodHandle> on <TypeHandle> in <Assembly>. Pertanto ottenere un tipo con 5000 caratteri nel nome richiede lo stesso tempo di cui uno con 5. I nomi effettivi vengono memorizzati in un posto separato nell'assieme: solo in modo che sia possibile utilizzare il reflection per ottenerli o per i compilatori (in altre parole, i nomi vengono memorizzati solo "per informazione"): si tratta dei metadati.

Penso che ci sia un modo per far sì che ILDASM ti dia il raw MSIL - ma non ne sono sicuro.

accessibili usando la riflessione

Perché si sta facendo un confronto di stringhe tra il nome del tipo che si desidera ed i nomi disponibili nel gruppo che fa la differenza: confronti di stringhe sono un O (n). Tuttavia, questa volta è minuscolo rispetto al costo totale di riflessione ed è completamente trascurabile (farà nanosecondi di una differenza) - non preoccuparti nemmeno di questo.

Sommario

Questo è il motivo per cui l'ottimizzazione prematura è davvero male - si presume che questo era un collo di bottiglia in cui, in realtà, non più veloce o più lento non c'è modo di farlo.

+0

Passando '/ bytes' a' ildasm' stampa un sacco di codici esadecimali per le cose, inclusi i codici operativi IL e (se applicabile) i token e le maniglie. Puoi anche farlo scaricare le tabelle dei metadati in forma grezza. –

+0

@JoshPetrie davvero. Vado di più per un'opzione "istruzioni IL, ma non cercare nomi per favore" - che io penso ** aveva: a meno che non mischiavo Cecil e ildasm. * Modifica: * Oh giusto, probabilmente lo era. –

+0

+1 Per rispondere alla domanda e spiegare * perché *. –

19

Risposta: No, la struttura della cartella del progetto e gli spazi dei nomi non avranno un effetto apprezzabile sulle prestazioni.

Una parola sulle prestazioni.

è scritto:

ottimizzazione prematura è la radice di ogni male.

Mi ricordo di essere un novizio.

Volevo avere il miglior codice di sempre.

Vedo che vuoi la stessa cosa.

Tuttavia, preoccuparsi di cose come questa non ti aiuterà.

Basta andare a scrivere alcuni giochi e fare esperienza.

Preoccupatevi delle prestazioni in seguito.

+2

Mi aspetto un [haiku] (http://en.wikipedia.org/wiki/Haiku)! –

+0

+1 per la poesia! – kaoD

+0

Così così incredibilmente corretto +1 – Valmond

-1

Lo spazio dei nomi piuttosto sicuro è solo una cosa C++. EG, quando nel disassemblatore xbox359 non ho punti di interruzione su cose come namespace. ecc. Cose come blah :: blahblah :: peoplewhosefoo si ridurrebbe a 38 < 000000> che, se ricordo, è il salto dal punto corrente puntatore dello stack al + < 000000> byte. Quale potrebbe essere quella funzione sopra descritta. Dove possono essere gli altri (non sono ancora un esperto in questa parte) ma creare locali di caricamento dello stack frame e inserire parametri su r4 a r < ...>.

Ma è possibile ignorare tutto questo testo e solo fare prima il gioco a 30 fps, quindi trovare gli hotspot/colli di bottiglia del codice e correggerlo. Piuttosto che questa ottimizzazione% 0,01.

Che è effettivamente ciò che è stato detto sopra in altre risposte.

+0

Non sta parlando di C++, ma di C#. Ma molto probabilmente è affrontato solo al momento della compilazione, sì. (E forse se qualche codice sta eseguendo una riflessione, ma è raro.) – Kylotan

+0

Ah, non ho notato il tag. –

3

L'organizzazione dei file di origine sul disco non influisce sulle prestazioni dell'assieme compilato. Né la profondità o l'ampiezza degli spazi dei nomi viene utilizzata all'interno del codice sorgente.

Quando si osserva lo standard ECMA per la CLI (n. 335), in particolare la Partizione II capitolo 22, è possibile trovare il formato dei metadati utilizzato per descrivere i tipi in un assieme (la tabella logica TypeDef). È possibile vedere che il nome del tipo e lo spazio dei nomi del tipo sono entrambi indici nell'heap delle stringhe: gli indici nei metadati CLI sono pseudo-dinamici, in quanto sono progettati per essere sempre una dimensione minima necessaria per indicizzare tutti gli elementi disponibili, quindi la dimensione dell'indice dell'heap della stringa in byte effettivi può variare ma sarà uguale per tutti i tipi.

Qualsiasi accesso allo spazio dei nomi o al nome attraverso i metadati sarà quindi un tempo costante nell'ambito di tale assembly. Analogamente, l'accesso ai dati che circondano l'indice del namespace sarà costante (non ci sarà bisogno di calcoli della lunghezza della stringa in tempo lineare per "saltare" la stringa del namespace nei metadati di tipo, poiché la stringa effettiva è nell'heap) .

Quindi non importa (*) importa quanti o quanto profondamente sono nidificati i vostri spazi dei nomi - fino a quando non li accedete nel codice tramite la riflessione e iniziate a eseguire operazioni di stringa lineare su di essi. Ma a quel punto è vero per qualsiasi operazione di stringa che esegui.

(*) il numero di spazi dei nomi unici e nomi e altre stringhe sarà ovviamente aumentare la dimensione dell'heap stringa, ma qualsiasi impatto che questo ha sulle prestazioni è estremamente basso livello e non è sempre necessariamente negativo.

Problemi correlati