Newsgroup: it.comp.lang.c++
Titolo: c++ e altri linguaggi

Demis (
mag...@hotmail.com
) wrote:
: Mi sapete dire praticamente perche' il c++ è preferito a altri
: linguaggi?
: Dal punti di vista pratico, oltre al fatto che ottengo eseguibili piu'
: efficienti, quali sono i vantaggi?
Dal mio punto di vista:
1) Pur essendo un linguaggio a basso livello di astrazione, una buona
   libreria gli consente di reggere il confronto con linguaggi piu`
  vicini all'uomo (tipo Pascal o VB).
2) e` molto flessibile... tanto per dirne una il supporto a piu`
   paradigmi di programmazione (procedurale, a oggetti, generica...)
   consente una piu` libera scelta al programmatore.
3) E` stato concepito per lo sviluppo e il mantenimento di grosse
   applicazioni e per la riusabilita` del codice (soprattutto con i template)
4) Compatibile quasi al 100%  con il C e a vantaggio di quest'ultimo
   possiede un ottimo type system.
5)  Adatto a qualsiasi tipo di applicazione (anche se da questo punto di vista,
  la sua genericita` a volte lo rende meno preferibile di altri linguaggi).
Paolo
 



efficienti, quali sono i vantaggi?
Un linguaggio OO e' intrinsicamente _meno_ efficiente di un linguaggio
standard. L'overload e' causato dal passaggio di parametri durante
la chiamata fra le varie funzioni membro oltre che dalle stesse
istruzioni CALL che sono discretamente `pesanti`.
~~
Roberto Colmegna
roberto...@login.it
... il tempo? Un amico che ci ricorda che
siamo vivi.

 [...]
Premesso che a mio parere comparare linguaggi procedurali e oo
rispetto all'efficienza e' come dire che un'auto consuma piu' benzina
di un cavallo (i due paradigmi hanno potenze espressive diverse,
quindi si paga per quel che si vuole), e' effettivamente vero che,
in C++ rispetto al C, c'e' un certo overhead dovuto al passaggio (nascosto)
di "this" per ogni chiamata di metodo e al lookup sulla vtable per
ogni metodo dichiarato virtual.
Questi svantaggi sono, generalmente, del tutto trascurabili *se* il design
del sistema e' ben fatto, e il linguaggio supporta (mediante dichiarazioni
static e la distinzione tra metodi virtual e no) il "downgrade" a chiamate
con efficienza C.
--
dr. Cristiano Sadun - Software Engineering and Consulting
***********Remove NOSPAM from address to reply***********
*********************************************************
"God is Real - unless declared Integer"

Cristiano Sadun (
cr...@NOSPAMsun6.itim.mi.cnr.it
) wrote:
 [...]
: quindi si paga per quel che si vuole), e' effettivamente vero che,
: in C++ rispetto al C, c'e' un certo overhead dovuto al passaggio (nascosto)
: di "this" per ogni chiamata di metodo e al lookup sulla vtable per
: ogni metodo dichiarato virtual.
: Questi svantaggi sono, generalmente, del tutto trascurabili *se* il design
: del sistema e' ben fatto, e il linguaggio supporta (mediante dichiarazioni
: static e la distinzione tra metodi virtual e no) il "downgrade" a chiamate
: con efficienza C.
Vero, ma innegabile e` anche il fatto che molte ottimizzazioni classiche
per linguaggi non OO non sono valide per linguaggi OO.
Prendiamo il caso della dead code elimination: da uno studio e` emerso che
programmi C presentano una percentuale di codice morto pari al 5% circa, nel
caso del C++ invece si arriva tranquillamente al 20%. E` emerso che il
problema non e` dovuto al linguaggio in se, ma al modo in cui l'ottimizzazione
e` condotta. In linguaggi OO sono spesso presenti classi basi che stabiliscono
un comportamento di defaultper quelle derivate, ma non di rado quelle derivate
quando ridefiniscono un metodo non richiamano quello della classe base.
Ora stabilire a compile time se un metodo venga richiamato e` difficile,
perche` non sono disponibili tutte le informazioni necessarie; a link time
invece la cosa e` fattibile, tutte le informazioni sono disponibili ma
spesso il link e` rimasto invariato!
Ovviamente l'eliminazione del codice morto non riduce semplicemente le
dimensioni dell'eseguibile, ma migliora le caratteristiche di localita`
spaziale del codice, tutti i processori dotati di cache ne trarrebbero
vantaggio (specie quelli con cache per dati e codice separate) e in particolare
le architetture a memoria paginata genererebbero meno page fault.
Molte altre assuzioni valide per i linguaggi "tradizionali" non lo sono piu` 
per linguaggi OO, mentre spesso altre prima non valide ora lo sono! 
Bisognerebbe adattare compilatore e link ai linguaggi OO, ma spesso
lo stesso front end viene utilizzato per linguaggi molto diversi tra loro!
Paolo Marotta

di un linguaggio OO ha lo stesso costo di un linguaggio "tradizionale"!
Vero, ma sul linguaggio tradizionale puoi contartele a mano, in un OO
ve ne sono talmente tante implicite che ti perdi prima se non conosci
esattamente la gerarchia di classi.


con efficienza C.
Chiedo venia, Dr., ma leggendo, e provando, si scopre che un programma
scritto in un linguaggio OO e' di media il doppio piu' grosso (a
livello d'eseguibile) ed almeno la meta' piu' lento dell'equivalente
scritto in un linguaggio non OO. Innegabilmente, comunque, l'esistenza
di dichiarare i metodi "inline" semplifica parecchio le cose ed
alleggerisce i tempi d'esecuzione attuando una sorta d'unroll a
livello di metodo.
Comunque sono assolutamente in accordo nel sostenere che l'OOP
presenta tali e tanti Vantaggi che consentono di appagare ampliamente
il costo delle CALL in eccesso. Salvo per i sistemi real-time!  >8-D))
Comunque se alla intel dedicasso un po' di cache allo stack non
sarebbe male.  :)


Colmegna Roberto (
Roberto....@login.it
) wrote:
: Stavo semplicemente riferendomi al fatto che, per ovvi motivi
: (...metodi) i linguaggi OO utilizzano passaggi di parametri su stack
: in modo molto piu' massiccio che i programmi scritti con linguaggi
: strutturati standard. A meno che i vari PUSH e POP vengano eseguiti
: in 0 cicli macchina, ma non mi pare sia cosi'!  ;)
C'e` solo un parametro in piu`: un puntatore!
: Cos'e' un linguaggio `imperativo`?
Per linguaggio imperativo si intende un linguaggio basato sul paradigma
imperativo, caratteristica tipica di questo paradigma e` la presenza di
istruzioni che modificano direttamente lo stato (assegnamento in primo
luogo). Quasi tutti i linguaggi odierni sono basati su questo paradigma,
compreso VB, Pascal, C, C++ (per la cronaca quello OO non e` un vero paradigma,
ma un metaparadigma!)
: >tecniche che non vanno affatto bene per i primi (non lo dico io, ma
: >ricerche scentifiche condotte in merito).
: Dove le trovo sul web?
C'e` un interessante articolo su Computer Programming N 47 (maggio 96)
: >Quanto alle call, esse si riducono sempre alla CALL del linguaggio macchina e
: >se sono inefficienti la cosa e` legata alle convenzioni di chiamata (quella
: >del C ad esempio e` meno efficente di quella pascal!).
: Calma! NON confondiamo l'istruzione assembly CALL col passaggio di
: parametri sullo stack!  Tale istruzione richiede (sopratutto nella
: versione FAR) ben piu' d'un paio di cicli di clock per essere
: eseguita. E, ovviamente, ben +` cicli d'una JMP FAR!
Infatti mi riferivo alle convenzioni di chiamata (che influiscono pesantemente
sulle prestazioni)!
Paolo Marotta

: all'incirca alla pari, seguiti a ruota da Basic e Modula. Nel mondo
: dell'intelligenza artificiale Lisp e Prolog stanno davanti a tutto.
Calme, qui le cose non sono cosi`  semplici. Nell'ambito dell'AI
classica (quella che si basa sulla manipolazione di simboli) LISP in
primo luogo e PROLOG in secondo luogo sono i piu` utilizzati, nell'ambito
della AI basata su reti neurali sono invece preferiti altri linguaggi...
Per quanto riguarda VB ritengo che il suo successo sia soprattutto (se non
unicamente) dovuto alla facilita` d'uso, facilita` che si paga in termini
che vanno ben oltre l'efficenza e si spingono fino alla flessibilita`.
Comunque personalmente non ho mai provato il VB, molti anni fa utilizzavo
il Basic dei commodore, ma da quando ho provato linguaggi quali il
Turbo Pascal e il C++ ho smesso di utilizzarlo (perdeva in potenza ed
espressivita`, e altre cosette...). Comunque almeno in ambito accademico
non e` ben visto!
Paolo Marotta

 eseguita. E, ovviamente, ben +` cicli d'una JMP FAR!
le versioni FAR di call/jmp esistono solo nei programmi a 16 bit,
percio` nei nuovi sistemi operativi non dovrebbero + esserci....
-- 
[Ranger, email: 
ran...@racine.ra.it
]

 sarebbe male.  :)
certo che c'e` la cache per lo stack, quando si dice 8K di cache per
i dati, lo stack e` compreso.
-- 
[Ranger, email: 
ran...@racine.ra.it
]

 Una valutazione precisa e`comunque difficile a farsi...
Ecco, qui c'erano le mie perplessita':bisognerebbe chiedere ad un hardwarista per
vedere come funzionano *precisamente* le cache usate oggi nei processori; parlando
di buffer cache di un s/o, ad esempio, mi viene naturale pensare che vengano...
cachate :)  le pagine di memoria, e quindi il tuo discorso e' corretto; a livello
di
cache su chip, pero', ho la sensazione che la granularita' sia un po' piu' fine.


Colmegna Roberto (
Roberto....@login.it
) wrote:
: >
: >C'e` solo un parametro in piu`: un puntatore!
: Ne sei sicuro?  A me pareva che si passasse altra `roba` sullo stack
: oltre al puntatore. Sopratutto su architetture intel/CISC dove i
: registri tendono ad essere POCHINI!   ;-D
Rispetto ad una pari funzione di un linguaggio non OO, al piu` c'e`
solo un puntatore (che spesso e` passato direttamente su un registro).
Quanto al fatto che i registri sono pochini... qui si va su considerazioni
che esulano i linguaggi OO...
Paolo

i dati, lo stack e` compreso.
Si, ma viene visto come una qualsiasi zona di memoria, non come uno
stack vero e proprio in riferimento alle istruzioni di PUSH/POP
eseguite +` di recente!


Colmegna Roberto (
Roberto....@login.it
) wrote:
: Affermazione pesante: si presuppone che l'eventuale codice presente al
: posto del codice `morto` sara' usato prima di un eventuale flushing
: di quel settore di cache. Cio' non e' molto probabile se appartiene
: ad un metodo, o addirittura, ad una classe differente.
Vero, tuttavia non e` possibile peggiorare la situazione rispetto al
caso in cui sia presente codice morto.
Tieni anche presente il famoso detto che dice che il 90% del tempo
viene speso nel 10% del codice... se riesci a scoprire quel 10% (con
un profiler) puoi fare in modo di inserirlo in un unico file (o comunque
di localizzarlo il piu` possibile), in questo caso caricata nella
cache una porzione di quel codice, e` probabile che il codice vicino
sia usato subito. In questo caso nella cache verrebbe a trovarsi una
situazione favorevole.
Ora ammetto che ci sono diversi se, tuttavia i pressupposti mi sembrano
piuttosto fondati, o no?
Paolo

dunque a ridurre le dimensioni dell'eseguibile.
Affermazione pesante: si presuppone che l'eventuale codice presente al
posto del codice `morto` sara' usato prima di un eventuale flushing
di quel settore di cache. Cio' non e' molto probabile se appartiene
ad un metodo, o addirittura, ad una classe differente.



Look here!  
http://www.winchip.com/products/arch.html
Sono le specifiche d'un chip intel-compatibile che, per la prima
volta, integra un stack-cache per 8 CALL/RET!  Si sono decisi!
_Forse_ e' la volta buona che l'OO comincera' a pesare un 30% in meno
rispetto ad ora.


piuttosto fondati, o no?
Decisamente SI!  :D
