PDA

View Full Version : static vs instance: quale dei due è più efficiente?


australopiteci
09-05-2009, 18:31
Salve a tutti,
sto imparando il c++ e avrei una domanda (che riguarda anche gli altri linguaggi): qualcuno sa dirmi la differenza in termini di efficienza (sia di velocità d'esecuzione sia in termini di memoria occupata) tra:

class pippo
{
private int pluto;
private int pinco;
public void esegui(void){ pluto = 5; pinco=4; stampa(pluto+pinco); }

}

class pippo
{
static public void esegui (int x,int y){x=5;y=4; stampa(x+y)}
}

So che usando metodi statici non si passa il riferimento a this ma comunque si usano due parametri in piu'.. accedere alle variabili d'istanza poi? è molto inefficiente?

ciao e grazie anticipatamente

71104
09-05-2009, 19:19
posto che non é una domanda che riguarda il C++ ma casomai la specifica implementazione del compilatore nonché la potenza dell'instruction set della macchina target, in linea di principio le performances sono equivalenti a meno che non si verifichino condizioni particolari che permettono al compilatore di stravolgere il codice effettuando forti ottimizzazioni a favore di un caso o dell'altro.

di conseguenza non é in termini di efficienza e di performances che devi ragionare quando ti trovi di fronte a quesiti del genere, ovvero non in termini di tempo-macchina, bensi di tempo-uomo che é molto piu importante del tempo macchina (siamo ben disposti a sacrificare un 10% di performance in cambio di un 10% di tempo in meno per il completamento del progetto); quindi in sostanza devi ragionare in termini di ingegneria del software: l'uso delle classi ti permette sostanzialmente di risparmiarti il passaggio di due parametri, e quando si tratta di semplificare decine di migliaia di righe di codice conta tanto anche quello.

australopiteci
09-05-2009, 19:29
posto che non é una domanda che riguarda il C++ ma casomai la specifica implementazione del compilatore nonché la potenza dell'instruction set della macchina target, in linea di principio le performances sono equivalenti a meno che non si verifichino condizioni particolari che permettono al compilatore di stravolgere il codice effettuando forti ottimizzazioni a favore di un caso o dell'altro.

di conseguenza non é in termini di efficienza e di performances che devi ragionare quando ti trovi di fronte a quesiti del genere, ovvero non in termini di tempo-macchina, bensi di tempo-uomo che é molto piu importante del tempo macchina (siamo ben disposti a sacrificare un 10% di performance in cambio di un 10% di tempo in meno per il completamento del progetto); quindi in sostanza devi ragionare in termini di ingegneria del software: l'uso delle classi ti permette sostanzialmente di risparmiarti il passaggio di due parametri, e quando si tratta di semplificare decine di migliaia di righe di codice conta tanto anche quello.

ciao, grazie per la risposta. Si, dal punto di vista dell'ing del software è molto meglio usare classi ma a me interesserebbe sapere esclusivamente la differenza in termini di velocità/memoria (solamente per curiosità).
E' scritto in tutti i testi di evitare le variabili globali. Essendo le variabili d'istanza simili a delle variabili globali, le si dovrebbero evitare il più possibile giusto (parlo sempre in termini di prestazioni)?

Tommo
09-05-2009, 19:39
Si dice di evitare le variabili globali unicamente per un discorso di ingegneria del software, cioè per l'Incapsulamento (http://it.wikipedia.org/wiki/Incapsulamento_(informatica)) dei dati...

non ha niente a che vedere con le prestazioni, e serve soprattutto per creare librerie più coerenti e stabili, e quindi facili da usare.
Cmq, anche se ci fosse una differenza fra static e non, probabilmente oggi è insignificante.

!k-0t1c!
09-05-2009, 20:23
Dal mero punto di vista delle performance un compilatore moderno dovrebbe produrre risultati migliori con la versione statica per le seguenti ragioni:

ECX non dovrà contenere alla chiamata il puntatore all'oggetto ed oltre a risparmiarne la scrittura potrà essere utilizzato dal chiamante per altri propositi in maniera più libera
Non dovresti avere nessun miss della cache per la lettura degli argomenti dallo stack, mentre se il tuo oggetto è allocato in un heap, *potresti* avere dei miss mentre legge i campi con i valori
*Potrebbe* produrre automaticamente una funzione con convenzione di chiamata __fastcall e quindi evitare l'accesso alla memoria (ovvero il push sullo stack) per il passaggio degli argomenti velocizzando così la chiamata

Nota che questi due vantaggi sono davvero irrisori data la potenza di un calcolatore di questi tempi. Ti consiglio pertanto di effettuare la scelta considerando la qualità del codice, la semplicità e la flessibilità della soluzione adottata (qualunque sia quella per cui opterai).

71104
09-05-2009, 22:15
Non dovresti avere nessun miss della cache per la lettura degli argomenti dallo stack, mentre se il tuo oggetto è allocato in un heap, *potresti* avere dei miss mentre legge i campi con i valori perché mai non dotresti avere dei cache miss sugli accessi allo stack? é un discorso statistico? o é un discorso relativo ad architetture particolari che magari usano stack veloci? (comunque non é il caso degli x86 e credo nemmeno degli x64)

gugoXX
09-05-2009, 23:40
In C# sono piu' performanti le chiamate a funzioni di istanza piuttosto che quelle statiche.
Meglio, in C# compilato per x86 a 32bit.
Una chiamata a procedura statica ha bisogno di 2 accessi in memoria per poter andare a prendere l'indirizzo finale, mentre una chiamata a procedura di istanza e' una jsr con spiazzamento.
Pensavo fosse l'opposto ma me ne sono accorto durante uno dei contest.
Non so invece relativamente ai dati.

australopiteci
10-05-2009, 15:52
Si dice di evitare le variabili globali unicamente per un discorso di ingegneria del software, cioè per l'Incapsulamento (http://it.wikipedia.org/wiki/Incapsulamento_(informatica)) dei dati...

non ha niente a che vedere con le prestazioni, e serve soprattutto per creare librerie più coerenti e stabili, e quindi facili da usare.
Cmq, anche se ci fosse una differenza fra static e non, probabilmente oggi è insignificante.


ok, grazie 1000

!k-0t1c!
10-05-2009, 17:56
perché mai non dotresti avere dei cache miss sugli accessi allo stack? é un discorso statistico? o é un discorso relativo ad architetture particolari che magari usano stack veloci? (comunque non é il caso degli x86 e credo nemmeno degli x64)
Discorso statistico basato su diverse esperienze passate di profiling. E quanto a x64 no, non hanno stack veloci, e su x64 il vantaggio di ECX libero calerebbe di importanza perché ci sono molti più registri a disposizione e questo renderebbe il discorso performance del tutto irrilevante :)


In C# sono piu' performanti le chiamate a funzioni di istanza piuttosto che quelle statiche.

Spiacente di deluderti ma il metodo è proprio sbagliato. Non puoi paragonare un linguaggio compilato da un JIT a uno compilato staticamente. Considera che un paragone che mischia un dato rilevato con -O0 e uno rilevato con -O3 è già insignificante in ambienti dove le performance sono importanti...Nello specifico comunque mi piacerebbe vedere dei dati con cui hai eseguito questo benchmark visto che è considerata buona pratica (riportata anche da FxCop per le performance) marcare un metodo come statico qualora non richieda this.

71104
10-05-2009, 18:33
Nello specifico comunque mi piacerebbe vedere dei dati con cui hai eseguito questo benchmark visto che è considerata buona pratica (riportata anche da FxCop per le performance) marcare un metodo come statico qualora non richieda this. questo mi pare banalmente ovvio visto che this é comunque un parametro a tutti gli effetti e va spinto anch'esso sullo stack :D
come dire che un metodo con un parametro in meno é sicuramente piu performante. poi é chiaro che con l'hardware di oggi per riuscire a vedere una minima differenza di performance bisogna mettercela tutta.

australopiteci
10-05-2009, 18:38
ciao, scusate ma non avevo letto le precedenti risposte..
usare la versione statica è dunque leggermente piu veloce??
ma questo solo in c# o anche in c++?

Tommo
10-05-2009, 18:46
Sinceramente mi sembrano "voli pindarici" (per non fare paragoni più grotteschi :asd:)

Allora che mi dite di quelle librerie dove TUTTI i metodi sono virtual?
Secondo questi ragionamenti si dovrebbe distruggere completamente le performance... dato che a runtime si deve pure fare il lookup nella vtable.

IMHO sottovalutate un pò i pc moderni :D

!k-0t1c!
10-05-2009, 19:19
questo mi pare banalmente ovvio visto che this é comunque un parametro a tutti gli effetti e va spinto anch'esso sullo stack :D

Sìsì, la questione è palese.
E comunque ripeto che salvo in contesti dove l'hardware è spinto ai veri limiti tutto questo discorso è una speculazione inutile.
Se volete ricavare la una privata da una chiave pubblica o studiare i comportamenti dei buchi neri all'avvicinarsi l'uno all'altro serviranno questi ed altri accorgimenti per metterci meno dell'eternità a finire i calcoli :)

gugoXX
10-05-2009, 21:14
Spiacente di deluderti ma il metodo è proprio sbagliato. Non puoi paragonare un linguaggio compilato da un JIT a uno compilato staticamente. Considera che un paragone che mischia un dato rilevato con -O0 e uno rilevato con -O3 è già insignificante in ambienti dove le performance sono importanti...Nello specifico comunque mi piacerebbe vedere dei dati con cui hai eseguito questo benchmark visto che è considerata buona pratica (riportata anche da FxCop per le performance) marcare un metodo come statico qualora non richieda this.

Cosa c'e' da deludere? Cosa ci sarebbe di sbagliato?
Ho guardato proprio i disassemblati, e i benchmark hanno poi dato ragione.
Quelle che erano classi statiche con metodi statici, una volta rese istanze e metodi d'istanza erano piu' performanti. E ovviamente sui contest ho poi agito cosi'.
Anche a me sembrava PALESE il contrario prima di provarci.

!k-0t1c!
11-05-2009, 01:43
Cosa c'e' da deludere? Cosa ci sarebbe di sbagliato?
Ho guardato proprio i disassemblati, e i benchmark hanno poi dato ragione.
Quelle che erano classi statiche con metodi statici, una volta rese istanze e metodi d'istanza erano piu' performanti. E ovviamente sui contest ho poi agito cosi'.
Anche a me sembrava PALESE il contrario prima di provarci.
Non contestavo tanto il risultato specifico, il quale pur sembrandomi dubbio (anche a causa dell'istruzione CIL callvirt usata per i metodi non statici di classi non sealed, risaputamente più lenta dell'istruzione CIL call), quanto l'affiancare C# a C++. Importa molto poi anche quali metodi sono ottimizzati, su cosa agisce l'inlining etc, ma tutto ciò ha poco senso alla luce delle considerazioni fatte prima sulle differenze comunque minime dei due approcci (e nello specifico non ha senso poiché C# non è usato in ambienti dove le performance contano tanto da ottimizzare per queste cose).

gugoXX
11-05-2009, 09:27
Non contestavo tanto il risultato specifico, il quale pur sembrandomi dubbio (anche a causa dell'istruzione CIL callvirt usata per i metodi non statici di classi non sealed, risaputamente più lenta dell'istruzione CIL call), quanto l'affiancare C# a C++. Importa molto poi anche quali metodi sono ottimizzati, su cosa agisce l'inlining etc, ma tutto ciò ha poco senso alla luce delle considerazioni fatte prima sulle differenze comunque minime dei due approcci (e nello specifico non ha senso poiché C# non è usato in ambienti dove le performance contano tanto da ottimizzare per queste cose).

A su questo non ci piove.
Ho infatti iniziato la frase con "In C# ...", volendo portare piu' che altro un contributo per chiunque lo usi, piu' che altro per confronto con C++

cionci
11-05-2009, 16:44
Thread chiuso
|
V
http://www.hwupgrade.it/forum/showthread.php?t=1649196