NSA - Non Solo Amiga

SOFTWARE => Linguaggi di programmazione e scripting => Topic aperto da: TheKaneB - 23 Aprile 2014, 09:22:41

Titolo: VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 23 Aprile 2014, 09:22:41
Un interessante articolo che analizza l'implementazione dello Switch Statement sul compilatore Visual C++.

In poche parole utilizza un sistema di tabelle per garantire salti con complessità O(1) nel caso in cui le label siano consecutive, O(log N) negli altri casi, usando un binary search tree a compile time. Nei casi banali lo switch viene automaticamente convertito in un if-else, per mantenere comunque il minor tempo di esecuzione possibile.

http://www.codeproject.com/Articles/100473/Something-You-May-Not-Know-About-the-Switch-Statem
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 23 Aprile 2014, 14:47:20
Se ne dicono tante di MS, ma VisualC++ spacca, c'e' poco da fare

Microsoft ha fatto tanti errori politici e commerciali (alcuni di stampo quasi mafioso), ma a livello tecnologico sono almeno 10 anni che regna, specialmente da quando hanno assunto il tipo danese ex Borland (l'inventore di Delphi e programmatore di Turbo Pascal) che è a capo del progetto .Net
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 23 Aprile 2014, 16:38:47
Bah; se parliamo di Visual Studio (IDE & such) allora posso concordare, ma parlando del compilatore C++ Microsoft non posso che dare un giudizio negativo (sopratutto quando parliamo di aderenza allo standard).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 23 Aprile 2014, 16:43:02
Bah; se parliamo di Visual Studio (IDE & such) allora posso concordare, ma parlando del compilatore C++ Microsoft non posso che dare un giudizio negativo (sopratutto quando parliamo di aderenza allo standard).

Io ho lavorato pesantemente con la versione 2005 di Visual C++ ed effettivamente masticava roba che tanto standard non era. Un po' come GCC diciamo.

Però ho letto cose molto positive su quest'ultima versione, ad esempio hanno rimosso quell'orrenda cosa che era il Managed C++ e hanno usato in maniera massiccia molte cose del C++11.

Comunque guardati anche C#, che è un linguaggio molto più moderno e ben progettato di C++. Su quel fronte MS ha fatto un ottimo lavoro.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 23 Aprile 2014, 16:54:58
Però ho letto cose molto positive su quest'ultima versione, ad esempio hanno rimosso quell'orrenda cosa che era il Managed C++ e hanno usato in maniera massiccia molte cose del C++11.

Eppure anche nella 2013 non hanno totale supporto a C++11, sia come linguaggio che come librerie (aneddoto stupido che mi è capitato: con std::atomic_int non compilava e dava strani errori, mentre con std::atomic<int> funzionava tutto correttamente; il primo è definito come un typedef (http://it.cppreference.com/w/cpp/atomic/atomic) dell'altro!).

Visto che il software che stiamo sviluppando deve compilare anche con VC++ (per mia scelta) oltre che a Clang, mi sta molto a cuore lo sviluppo del compilatore Microsoft, ma non è possibile che ogni volta che facciamo il merge della codebase ci sia qualche puttanatina che su VC++ non va.
Spero seriamente che con VS2014 sistemino sta cosa, anche se gli altri compilatori (addirittura GCC!) sono già pronti per C++14 (Clang 3.4 ha totale supporto alla bozza dello standard attuale) :(.

Citazione
Comunque guardati anche C#, che è un linguaggio molto più moderno e ben progettato di C++. Su quel fronte MS ha fatto un ottimo lavoro.

Lo guarderò, ma a tempo perso, visto che il software che sviluppo deve essere multipiattaforma (Win/Mac/Linux e possibilmente altro, ma queste tre principalmente), e non voglio trafficare per trovare un compilatore C# che gira su Linux (per sviluppo) e/o librerie adatte (Mono l'ultima volta che ho controllato era un mezzo cesso).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 23 Aprile 2014, 17:01:01
probabilmente è ancora presto per buttare Mono nel cesso, ma a inizio mese MS ha rilasciato Open Source il suo compiler e gran parte del framework .Net http://roslyn.codeplex.com/ :)

Licenza Apache 2.0
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 23 Aprile 2014, 18:39:35
Boh, vedremo come si evolve la situazione.

Per il momento mi tengo stretto il mio bel elefante (http://channel9.msdn.com/Events/GoingNative/2013/Opening-Keynote-Bjarne-Stroustrup). ;D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 23 Aprile 2014, 22:19:14
Un interessante articolo che analizza l'implementazione dello Switch Statement sul compilatore Visual C++.

In poche parole utilizza un sistema di tabelle per garantire salti con complessità O(1) nel caso in cui le label siano consecutive, O(log N) negli altri casi, usando un binary search tree a compile time. Nei casi banali lo switch viene automaticamente convertito in un if-else, per mantenere comunque il minor tempo di esecuzione possibile.

http://www.codeproject.com/Articles/100473/Something-You-May-Not-Know-About-the-Switch-Statem
Articolo molto bello e istruttivo. Danke! :)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 24 Aprile 2014, 10:47:14
Boh, vedremo come si evolve la situazione.

Per il momento mi tengo stretto il mio bel elefante (http://channel9.msdn.com/Events/GoingNative/2013/Opening-Keynote-Bjarne-Stroustrup). ;D

Già, aspettiamo :)

Quello che mi "preoccupa", in senso lato, è che il nuovo C++ è così diverso dal vecchio C++ '98 da risultare quasi un nuovo linguaggio a sè stante. Questo significa che i vecchi programmatori tenderanno per inerzia a non usare le novità e i nuovi programmatori non saranno attratti da questo mondo, continuando a preferire linguaggi diversi e più semplici (Java e C# attualmente sono i più diffusi in ambito enterprise).

Dal canto mio sto cercando di reintrodurre il C++ nel mio workflow quotidiano usando Qt per le app mobili, ma non mi sono addentrato nei meandri dei nuovi standard più per mancanza di tempo che altro.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 24 Aprile 2014, 16:53:54
Quello che mi "preoccupa", in senso lato, è che il nuovo C++ è così diverso dal vecchio C++ '98 da risultare quasi un nuovo linguaggio a sè stante. Questo significa che i vecchi programmatori tenderanno per inerzia a non usare le novità e i nuovi programmatori non saranno attratti da questo mondo, continuando a preferire linguaggi diversi e più semplici (Java e C# attualmente sono i più diffusi in ambito enterprise).

Secondo me, non è poi "così diverso"; C++11 ha introdotto varie cose ma in realtà cose che i programmatori desideravano da molto e che sono di immediata applicabilità.

Esempi:
- l'uniform initialization (http://mbevin.wordpress.com/2012/11/16/uniform-initialization/) che ti permette di inizializzare variabili e/o chiamare costruttori sempre usando le parentesi graffe; un esempio banale:
Codice: [Seleziona]
class Point {
    Point(int x, int y)
     ....
};
....
Color getPointColor(Point p);
....
Color c = getPointColor({4, 6});

- la parola chiave auto (http://mbevin.wordpress.com/2012/11/13/auto/) per determinare automaticamente all'inizializzazione il tipo di dato della variabile, comodo specialmente quando hai tipi templatizzati il cui nome è estremamente lungo (gli iterator per esempio).
- il range-based for (http://mbevin.wordpress.com/2012/11/14/range-based-for/) (for(Tipo variabile : contenitore))
- Gli smart pointer (http://en.cppreference.com/w/cpp/memory) sono migliorati e ce ne sono 4 tipi in base a come vuoi gestire l'oggetto
- Finalmente c'è un ordinamento della memoria ben definito e supporto di libreria per operazioni atomiche (http://en.cppreference.com/w/cpp/atomic) e thread (http://en.cppreference.com/w/cpp/thread) di base.
- Il move semantics (1 (http://blog.smartbear.com/c-plus-plus/c11-tutorial-introducing-the-move-constructor-and-the-move-assignment-operator/), 2 (http://www.avid-insight.co.uk/2013/05/understanding-cpp11-move-semantics/))permette di scrivere il codice in modo più naturale anche lavorando con grossi oggetti, perchè limita al minimo il numero di copie che un oggetto subisce.

Tra queste cose che ho detto, le prime 4 possono essere usate fin da subito anche in un vecchio progetto, perchè non richiedono di reingegnerizzare il codice esistente; il threading ovviamente avvantaggia applicazioni parallele, anche se se una applicazione aveva bisogno dei thread, probabilmente si è creata le sue astrazioni e/o ha usato una libreria di terze parti.
Il move semantics è la cosa meno applicabile immediatamente, perchè un po' obbliga a ripensare a come trattare gli oggetti; in realtà in molti casi il lavoro di conversione può essere fatto solo nella classe stessa e il resto del codice continuerà a compilare e funzionare, però se l'applicazione è molto grande e con uno stile ben definito, può essere il caso di lasciarla com'è.

Quello che credo io è che, anche se magari C++ non crescerà prendendo nuovi programmatori, i correnti programmatori C++ avranno un tool molto più potente e pratico per costruire nuovi software o per perfezionarne vecchi, e secondo me non è una brutta cosa. :)


PS: i link che ho messo li ho presi velocemente per dare un riferimento a cosa sto dicendo; magari non sono i documenti migliori.
PPS: Dimenticavo le Lambda expression (http://en.cppreference.com/w/cpp/language/lambda)!
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 25 Aprile 2014, 06:58:31
Io lo considero un altro linguaggio, perché cambi il modo di programmare con C++0x11.

Comunque a me non piace come linguaggio perché, a parte la sintassi che mi sta proprio indigesta, è troppo complesso: per lavorarci e sfruttarlo al meglio serve tanta, tanta esperienza e un notevole esercizio di memoria.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 25 Aprile 2014, 07:00:38
Le considerazioni fatte per lo switch statement non sono una prerogativa del compilatore Microsoft, ma di qualsiasi optimizing compiler.

Ci sarebbero tante cose da dire sullo switch statement del C (diverso dal case statement del Pascal) che rende difficoltosa la generazione della jump table. Alcune considerazioni fatte nell'articolo non valgono. Purtroppo non ho più tempo per dilungarmi nei forum :-(
Peccato, perché adoro questo tipo di discussioni. Ricordati che oggi è venerdì, e c'è pure il fine settimana davanti. :P
Citazione
Nei casi banali lo switch viene automaticamente convertito in un if-else, per mantenere comunque il minor tempo di esecuzione possibile.

I casi banali sono per n molti piccoli (n << 5), diversamente la jump table ha prestazioni migliori.

(http://oi61.tinypic.com/vnmmtx.jpg)
SE hai tempo, mi piacerebbe sapere quale sarebbe la masksearch instruction.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 25 Aprile 2014, 22:52:23
Grazie per il paper. E' stato interessante per i dati presentati, anche se conferma l'idea che m'ero fatto intuitivamente su quest'argomento.

Comunque già da ieri mi frullano diverse idee su come implementare diversamente il caso di case/switch con diversi valori (quindi non pochi, ma nemmeno tantissimi), ma sparsi (entro un intervallo non troppo ampio). Ho in mente anche alcune soluzioni con hardware dedicato. Vediamo cosa posso tirare fuori in futuro.

P.S. Io passo ben più di 40 ore settimanali al computer: all'incirca il doppio. :-\

Dimenticavo: sul C++ sono d'accordo con te e con le citazioni che hai riportato. ;D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 26 Aprile 2014, 04:04:22
Io lo considero un altro linguaggio, perché cambi il modo di programmare con C++0x11.

Se con C++0x11 parli di C++17, allora un po' posso darti ragione: per quella versione (se tutto va bene) è previsto l'inserimento di moduli (per sostituire gli #include), i concept lite (di cui posso capire la motivazione, però boh non mi convincono ancora) e molta altra roba sopratutto in libreria... quindi si, sarà un bel salto. ;D

In C++11, come dicevo prima, ci sono cosa nuove e importanti (move semantics in primis), però cose che già i programmatori volevano ed eventualmente cercavano di raggirare con altra programmazione; semplicemente ora possono scrivere nel modo più naturale senza fare workaround.
Non lo considero un "nuovo linguaggio", altrimenti una qualsiasi aggiunta di un nuovo algoritmo alla libreria di qualsiasi linguaggio implicherebbe un "nuovo linguaggio", perchè i programmatori possono usare quella versione invece di implementarsi la propria. :D


Posso catalogarlo come il peggior libro che ho letto sul language design e software engineering,

Forse perchè non vuole essere un libro sul "language design e software engineering" ma solo sulla storia e evoluzione del C++, che sicuramente non è stato un lavoro da accademia ma un'evoluzione "sul campo" (con tutti i problemi che ciò comporta).

Però non posso dire niente perchè non lo ho letto; ho da leggere "A Tour of C++" così for the lulz, visto che è menzionato in quel video che ho linkato.

Secondo me, non è poi "così diverso"

Il C++ per come venne concepito da Stroustrup non ha nulla a che vedere con il C++ di oggi.

Posso essere d'accordo, però la discussione iniziale era C++11 vs. vecchio standard (che tecnicamente sarebbe C++03, però a tutti gli effetti si considera C++98), e in questo lo considero "non così diverso".

Oggi non si può dire ciò sui compilatori C++ e credo che per i suoi progetti oggi nemmeno lo utilizzi. Lo stesso Stroustrup fa capire in alcune parti che da quando si è messo in mezzo il working group del C++ standard committee, il suo linguaggio ha perso di semplicità. Addirittura ha scritto che alcune delle feature aggiunte successivamente sono pure troppo per lui.

Guarda, l'idea che mi son fatto io (anche vedendo dove stanno puntando con le nuove revisioni), è che hanno visto come il C++ stia perdendo spazio ad altri linguaggi più snelli e pratici come Java e C# (oddio, definire pratico e snello il Java... ::) è un azzardo, però dai diciamolo for the sake del discorso), e di come hanno lasciato passare questo fatto per troppo tempo (C++11 c'ha messo i suoi bei 13 anni a completarsi), e quindi stiano cercando di ripulirlo e modernizzarlo.

Il problema però è che devono rimanere il più possibile compatibili con tutti i vecchi sorgenti decennali ancora richiesti (altrimenti è facile fare un nuovo linguaggio!), quindi l'unico modo che hanno è aggiungere funzionalità; questa cosa si vede un po' in tutto, prendiamo ad esempio OpenGL che nelle versioni 4+ sta diventando una API molto snella... se consideri solo le cose più nuove. Quì il problema è un po' diverso, perchè se mentre col C++ puoi usare l'ultimissima versione che il compilatore supporta, con OpenGL devi tener conto della versione che i driver dei tuoi clienti supportano, quindi anche io ad esempio devo programmare su un OpenGL <3.3 (principalmente perchè come requisito il programma deve funzionare anche su Linux con i driver open source, che sono arrivati solo a 3.3). Come reference posso dire che le funzioni molto comode che mi servirebbero sono in OpenGL 4.3 e 4.4.

Ora, ritornando al C++, è vero che ha tante cose dentro, ma non è detto che bisogna usarle, anche perchè ci sono robe introdotte malamentre e praticamente inusabili (esempio classico è la parola chiave export (http://en.cppreference.com/w/cpp/keyword/export), che ha una funzione talmente assurda e complessa che esiste un solo compilatore (http://www.comeaucomputing.com/) in grado di compilarla, e gli sviluppatori dello stesso compilatore scoraggiano gli altri programmatori a provare a implementarla).

Io ritengo di usare un buon set di funzionalità del C++ (programmazione procedurale, oggetti, ereditarietà, classi virtuali pure [a mo di interfaccia], template [per un momento abbiamo anche usato template metaprogramming, poi son cambiati un po' i requisiti e rigirando il codice non ne avevamo più bisogno], molte contenitori e funzioni di libreria), e ora spero di usare di più ancora le nuove funzionalità di C++11; molte come la move semantics la uso già (sia nelle classi che scrivo io, sia sfruttandone il supporto da parte della libreria standard), e fra non molto sfrutterò anche i thread e la sincronizzazione (almeno così non dovrò includere boost.thread come dipendenza).

A me piacerebbe TANTISSIMO che per C++17 mettessero molte cose come "deprecated" e con uno switch da compilatore per disabilitarle tutte; lo attiverei subito. ;D

Aggiungo come mio solito fare un quote sul C++:
Citazione
If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor and when was the last time you needed one?
— Tom Cargill

A me pare una supercazzola; come fa a essere protected e private allo stesso tempo? ???

Come chicca finale, imparate a memoria ciò:
Citazione
    The body of a destructor is executed before the destructors for member objects. Destructors for nonstatic member objects are executed before the destructors for base classes. Destructors for nonvirtual base classes are executed before destructors for virtual base classes. Destructors for nonvirtual base classes are executed in reverse order of their declaration in the derived class. Destructors for virtual base classes are executed in the reverse order of their appearance in a depth-first left-to-right traversal of the directed acyclic graph of base classes; “left-to-right” is the order of appearance of the base class names in the declaration of the derived class.

– Bjarne Stroustrup, The C++ reference manual, section 12.4.

In realtà non è poi così strambo: ti dice che prima distrugge te, poi distrugge i tuoi membri (nell'ordine inverso di costruzione aggiungerei), e poi passa a distruggere le classi base. Sulla storia del grafo aciclico devo ragionarci un po' su, ma credo che intenda semplicemente dire che, nell'ordine in cui hai dichiarato le classi da cui erediti, lui prende la prima e distrugge tutti i suoi discendenti, poi prende il secondo etc.
Dammi un po' di tregua, son le 4am! ;D *


* Ecco in questo caso puoi rispondere che "Eeeeh in <linguaggio> puoi capirlo anche se sono le 4 di mattina etc etc. :-P"
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 26 Aprile 2014, 06:36:18
Appunto. Perché altri linguaggi non hanno quella mostruosa complessità del C++. ;)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 26 Aprile 2014, 11:33:15
Ed è il motivo per cui mi sono convertito a Python. Sebbene non sia affatto assente da critiche in tal senso (le metaclassi fanno venire il mal di testa), in generale è un linguaggio semplice e veloce da padroneggiare.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 26 Aprile 2014, 14:27:40
Per questo è meglio che ci sia qualcuno che imprima una precisa direzione. E' il caso di Python, dove lo sviluppo del linguaggio, della VM, e della libreria, è ovviamente affidato a un folto gruppo di sviluppatori, ma Guido, il creatore del linguaggio, rimane il "benevolo dittatore" e si esprime sui cambiamenti, arrivando a "mettere il veto" quando lo ritiene opportuno (es: sulle tail call, i break "labelled", lo switch/case, il do/while, ecc.).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 27 Aprile 2014, 14:56:27
Purtroppo quel libro è disponibile soltanto in versione cartacea. Dopo aver comprato il Kindle, non ho proprio voglia di prendere altra roba "scomoda", e per giunta costosa.

Comunque ho letto velocemente sulla paginetta wiki di Modula-3 che l'operator overloading fu scartato perché ritenuta una funzionalità complicata e pericolosa? Posso capire che tracciare l'esecuzione reale del codice possa diventare più difficile, ma pericolosa?
Sull'ereditarietà multipla nulla da dire, invece. In Python l'ho usata pochissime volte, e sostanzialmente come "mixin".
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 27 Aprile 2014, 16:37:19
Purtroppo quel libro è disponibile soltanto in versione cartacea. Dopo aver comprato il Kindle, non ho proprio voglia di prendere altra roba "scomoda", e per giunta costosa.

E' un libro fantastico (la libreria di I/O è la più performante che ci sia).
Per questo volevo prenderlo. :) Ho visto anche un po' di recensioni, e ne parlano benissimo. Poi io rimangono ancora di matrice pascal-wirthiana, per cui vado a nozze quando trovo materiale informatico che parla o fa uso di linguaggi come questi.
Citazione
Comunque il capitolo più menzionato da libri di compilatori o di design è "How the language got its spots"
OK, grazie.
Citazione
Comunque ho letto velocemente sulla paginetta wiki di Modula-3 che l'operator overloading fu scartato perché ritenuta una funzionalità complicata e pericolosa?

Credo che pericoloso sia riferito al multiple inheritance e che complicating sia riferito all'operator overloading
Ah, bene. Ha molto più senso.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 27 Aprile 2014, 18:41:03
Ma come, dov'è il mio messaggio!?
Avevo scritto una risposta relativamente lunga ieri, è andato perso... :'(

Se mi ricordo bene, avevo dato come esempio di problema con la standardizzazione da parte di molte persone l'introduzione di memory_model_relaxed (qui (http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2) e qui (http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2), quello che dico è nel secondo) nei std::atomic<> di C++11 perchè sulle architetture POWER e ARMv7 il modello SC-DRF con le barriere acquire/release avrebbe introdotto delle full memory barrier che avrebbe ucciso le prestazioni, perciò IBM e ARM hanno insistito per inserire questa modalità (che deve essere specificata esplicitamente cmq).
I due video son simpatici, tenuti da Herb Sutter; di C++ c'è ben poco, è praticamente un'introduzione sui modelli della memoria e come (non) usare le barriere di memoria.

Poi avevo scritto una mia interpretazione dell'"indovinello" (prima di leggere la soluzione) dopo aver appreso che "base" non era un altro aggettivo di "destructor" (/me fails at english...): avevo preso praticamente quasi tutto giusto, eccetto che "abstract virtual base" l'avevo tradotto in "una classe base che ha almeno un metodo virtuale puro (quindi è astratta e non si può istanziare; in questo caso già il distruttore è il metodo virtuale puro)", mentre lui intendeva la "virtual inheritance (http://en.wikipedia.org/wiki/Virtual_inheritance)" che non conoscevo o che mi ero dimenticato visto che non la ho mai usata.

Poi avevo espresso il mio dissenso verso l'ereditarietà multipla, che sarebbe una delle cose che andrebbero "deprecate" e incluse in quel famoso switch del compilatore di cui parlavo prima; avevo anche detto di togliere l'ereditarietà public/protected/private e fare solo la public, visto che le altre son usate estremamente di rado e spesso si può raggirare scegliendo in modo più preciso il livello di protezione direttamente nella classe base. Le interface a mo di Java sarebbero carine da inserire (forse necessarie togliendo l'ereditarietà multipla), e lato compilatore non sono per niente difficili da implementare, perchè si possono considerare come classi con solo metodi virtuali puri (e distruttore virtuale implicito), e poi si possono usare le stesse tecniche dell'ereditarietà multipla.

Concludevo che, alla fine, il C++ usato e utile è cmq un subset del totale (anche solo per il famoso export); se "deprecassero" le funzionalità più arcane o che son state inserite in fretta e furia, il codice vecchio continuerebbe a compilare, ma il codice nuovo lo si può creare direttamente nel modo "nuovo" e più appropriato.
Stroustrup dovrebbe anche difendere la sua creatura; magari lo standard "ristretto" non sarà nell'ISO, ma son sicuro che la comunità (specialmente open source) sarebbe disposta ad ascoltarlo, è pur sempre un nome conosciuto...


Praticamente il Type System non è a conoscenza del genericity, i moduli generici vengono istanziati da quake (il make tool di Modula-3) e il compilatore si ritrova solo i moduli specializzati. Questo elimina un sacco di problemi tipo un type system complesso e il code bloating/memory hogging dei template C++.

Non ho ben capito, riesci a farmi un esempio?
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 27 Aprile 2014, 21:42:48
Intendo un esempio di tipo di dato generico, che viene specializzato in vari tipi, e di come appare nel codice macchina generato; ovviamente non intendo istruzione per istruzione, ma di come il codice distingue tra le specializzazioni senza ripetere il codice (modello C++) o Java (con codice generico che lavora tramite puntatori e va di boxing/unboxing).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 28 Aprile 2014, 18:31:36
Non so cosa tu intenda che per il modello del C++ non ci sia codice duplicato, tutto l'opposto. Sarò breve, perché ho il tempo contato con il contagocce.

Non hai letto bene: la frase (probabilmente scritta male) è da leggere come "distingue tra le specializzazioni senza o ripetere il codice (modello C++), o fare come Java[...]".
Il modello C++ è "ripetere codice", non "senza ripetere codice". :D

Limitare il genericity solo ai reference object è la soluzione adottata da ISO-Modula-2, Modula-3, Oberon-2ext, Java.

Ottimo, questo risponde al dubbio che avevo prima.

Shared object:

Il codice generato è unico per tutti i casi possibili. Vengono utilizzate le classi estese più grosse (T2 e P2) e le classi base vengono allocate con un padding tutte della stessa dimensione.
Per il parametro basic type viene usato il basic type più grande rappresentabile.

Numero totale di codice oggetto per classe: 2, numero funzioni: 2.

Vantaggi: Velocità di compilazione, easy debugging, no code bloating.

Svantaggi: Il codice delle classi occupa leggermente di più, overhead sui basic type, aritmetica lenta (gli interi vengono usati all'intero più grosso di 128 bit, i float sono tutti a precisione doppia, etc..).

Capito, quindi lascia un pochino l'efficienza di esecuzione per facilitare la programmazione e la compilazione. Ottimo.
(il numero di codice oggetto dovrebbe essere 1, non 2)


Quanti sono i primitive type in C++? 14? 9*2*14 = 252 funzioni in totale. Il C++ linker ovviamente eliminerà gran parte (se non quasi tutte) le istanze non utilizzate, ma sta di fatto che il compilatore per motivi di type checking andrà a generare tutto questo garbage.

Si beh, ovviamente questo assumendo che in un programma vengano richieste le specializzazioni per tutti i tipi: se vengono richieste due specializzazioni vengono compilate solo quelle, non è che il compilatore compila ad oltranza. :P

Vantaggi: Storage economy nell'allocazione delle classi, no overhead sui basic type, nessuna influenza sull'aritmetica.

Un altro vantaggio è che, poichè ogni specializzazione del template è come se fosse stata scritta a mano, il compilatore può ottimizzare il codice per ogni singola specializzazione; spesso questo (poichè quando il compilatore crea la specializzazione usata da un qualche altro codice ha a disposizione l'intera implementazione delle funzioni) si traduce nell'inline delle funzioni templatizzate nel codice della funzione chiamante, e permette ulteriori ottimizzazioni.

Questo ad esempio è molto utile con template di strutture dati che sono semplici nel loro codice, ad esempio una lista concatenata dove l'inserimento/eliminazione è solo un'assegnazione di qualche puntatore: in questo caso il codice finisce direttamente nel codice della funzione chiamante, a efficienza di esecuzione (si risparmia la chiamata a funzione etc).


Cmq grazie della spiegazione. :D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 29 Aprile 2014, 00:15:09
Se consideri l'istanziamento del generic/template sì, ma forse mi sono espresso male, mi riferisco qui all'object code delle classi, essendo 2 (indipendentemente dalle estensioni, dato che viene fatto il padding prendendo la classe con dimensione più grande) ci sono 2 object code per due classi. Invece se si vanno a considerare le estensioni sono 3+3 (6) object code, in tal modo si risparmia quando si alloca su stack.

Non mi riferivo al codice che va ad istanziare il generic/template (che sarebbe in questo caso il numero di funzioni). Forse tu consideri un template class (in questo caso sì, solo una istanza, anche se sarebbe da considerare a parte), in Ada il genericity è a livello modulare quindi ho considerato solo l'istanziamento delle due funzioni (che sarebbe 1 istanziamento del generic).

Ok, penso di aver capito un po' meglio; mi servirebbe conoscere un po' meglio Ada, ma per il momento la risposta mi soddisfa. :D

No, se sono typechecked vengono istanziate tutte, poi quelle inutilizzate vengono rimosse dal linker.

(Tu dirai, che ne può sapere se non conosce il C++?) Da Programming Language Pragmatics:
Citazione
In the usual case, the compiler creates a separate copy of the code for every instance. (C++ goes farther, and arranges to type-check each of these instances independently.)
[...]
C++ will create specialized implementations of a generic for different built-in or value types.
[...]
C++ is by far the most ambitious. Its templates are intended for almost any programming task that requires substantially similar but not identical copies of an abstraction.

Mmmmmh... però da quella frase non è detto che debba per forza girare la passata di machine code generation, mi spiego: il compilatore C++, quando trova un template, lo parsa e si segna tutti i dati importanti nell'AST & co., e poi usa questa rappresentazione per fare i chek sui tipi, e passa alla generazione del codice solo quando ha deciso che effettivamente la specializzazione si ha da compilare.

(Ovviamente se c'è scritto per inciso sul libro che genera pure tutto il codice, ignora quel che dico :P)

Se ti interessa il language design ed il language implementation, è un must (1000 pagine circa).

Me lo segno tra i libri da leggere; è un argomento che mi interessa molto, anche se il tempo è poco. :D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 29 Aprile 2014, 11:51:23
Ehm, non credo sia possibile fare type checking su un template non istanziato :P a meno che non ci sia qualche metodo che non conosco. Il type checking richiede che tutti i tipi di un determinato blocco facciano parte della symbol table, in modo tale che dopo il lookup si hanno informazioni sugli operatori implementati da quel tipo (=, <, o >=, etc).

Quello che intendo dire è che, metti di avere una funzione a caso:
Codice: [Seleziona]
template<typename T>
T modulo(T a, T b) {
    return a % b;
}
...
int res = modulo(10, 5);

Prima di tutto un compilatore fatto bene ha abbastanza informazioni per sapere di dover elaborare solo "int modulo(int, int)", ma anche se si mettesse a istanziare il template per tutti i tipi base T = {char, short, int, float, double, unsigned,...}, non è detto che debba anche generare il codice macchina per tutti quelli, quindi ad esempio nel codice oggetto per il file che contiene quel codice non ci sarà il codice oggetto per "char modulo(char,char)", "short modulo(short,short)" etc, ma solo "int modulo(int, int)".

In questo senso "il compilatore non compila a oltranza".

In realtà c'è una soluzione a questo problema, ovvero il constrained genericity (http://en.wikipedia.org/wiki/Generic_programming#Constrained_genericity) di Eiffel, nella definizione del template puoi passare determinate interfacce di tipi, prendendo l'esempio di wikipedia in quel caso puoi passare solo tipi che implementano l'interfaccia comparable (=, !=, <,>, <=, >=).
Qui puoi fare un po' di type checking senza istanziare il template prima, perché conosci un minimo di informazioni sugli operatori che implementa

Assomiglia ai concepts (http://en.wikipedia.org/wiki/Concepts_%28C++%29) (o meglio, i concepts assomigliano a quello) che si stanno progettando per il prossimo standard di C++.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 29 Aprile 2014, 20:49:18
Io mi chiedo perché concetti semplici e lineari devono renderli immensamente complicati in C++, i concepts sono estremamente perversi rispetto al constrained genericity. Basterebbe solo che implementassero le interfacce

Per questo hanno addirittura dovuto lasciare l'idea originale e creare i Concepts Lite (http://isocpp.org/blog/2013/02/concepts-lite-constraining-templates-with-predicates-andrew-sutton-bjarne-s)! ;D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: fulvio - 30 Aprile 2014, 13:15:25
Limitare il genericity solo ai reference object è la soluzione adottata da ISO-Modula-2, Modula-3, Oberon-2ext, Java.

Ci sono due code pattern generation: lo shared object (di Ada) e specific object instantiation (di C++).

Immaginiamo di avere un generic package o template che accetta due classi con tre livelli di extension ed un tipo basic type come parametro, vengono usate per due funzioni all'interno del package/template. Classi T, T2 (estende T), T3 (estende T2), P, P1 (estende P), P2 (estende P1).


Shared object:

Il codice generato è unico per tutti i casi possibili. Vengono utilizzate le classi estese più grosse (T2 e P2) e le classi base vengono allocate con un padding tutte della stessa dimensione.
Per il parametro basic type viene usato il basic type più grande rappresentabile.

Numero totale di codice oggetto per classe: 2, numero funzioni: 2.

Vantaggi: Velocità di compilazione, easy debugging, no code bloating.

Svantaggi: Il codice delle classi occupa leggermente di più, overhead sui basic type, aritmetica lenta (gli interi vengono usati all'intero più grosso di 128 bit, i float sono tutti a precisione doppia, etc..).


Specific object instantiation:

Viene istanziato codice per ogni classe in ogni sua estensione e per ogni basic type.
Trattiamo prima il caso delle classi:
Le classi vengono istanziate in ogni loro estensione, T, T1, T2, P, P1, P2. Il codice del template (le due funzioni) viene allocato per ogni coppia: T, P;  T, P1;  T, P2; ... T3, P3;

Numero totale di codice oggetto per classe: (3+3) 6, numero funzioni: 18 (3*3 * 2).

Quanti sono i primitive type in C++? 14? 9*2*14 = 252 funzioni in totale. Il C++ linker ovviamente eliminerà gran parte (se non quasi tutte) le istanze non utilizzate, ma sta di fatto che il compilatore per motivi di type checking andrà a generare tutto questo garbage.

Vantaggi: Storage economy nell'allocazione delle classi, no overhead sui basic type, nessuna influenza sull'aritmetica.

Svantaggi: Super code bloat, ultra slow compilation time, nightmare debugging.

I template del C++ sono comunque (inutilmente) molto avanzati e complicano di tantissimo questo code pattern generation. Non sono un esperto di C++ per poter dire di più.

Mi dilungherei sulle alternative/varianti ma per ora non posso, non ho nemmeno riletto per vedere se ho scritto inesattezze

Questo thread è davvero interessante, mi dispiace solo di non avere molto tempo. Se pur sono d'accordo su praticamente tutto quello che dice dsar, vorrei mettere solo un secondo le cose in prospettiva: molte delle cose cattive del C++ vengono dalla sua necessità di includere il C (quasi del tutto) e rimanere per lo più compatibile con esso. Certo ci sono scelte che potevano essere fatte diversamente, ma se il tuo primo vincolo è "devo rimanere compatibile con il C" allora diventa più difficile fare le cose diversamente da come sono state fatte (è una intuizione perchè non ho pensato seriamente ha come poteva evolvere il C++ senza quel vincolo).

Il libro di Stroustrup comunque non è di language design, è più una introduzione al linguaggio. So che scrisse un altro libro, "The Design and Evolution of C++", dove spiegava il perchè di molte scelte, ma non l'ho mai letto.

Sui template anche io sono d'accordo che è un meccanismo inutilmente complicato (tant'è che è turing complete) ma se ne sono accorti e hanno introdotto constexpr anche per questo, avere computazioni a compile-time senza l'uso della metaprogrammazione. Se ti limiti ai concetti base, quando i concept lite saranno implementati scrivere una funzione che calcola la media di una sequenza sarà una cosa come:

Codice: [Seleziona]
auto mean( Sequence seq )
{
  return std::accumulate( begin(seq), end(seq), 0.0 ) / seq.size(); 
}

Questo sarà effettivamente un template, anche se non c'è bisogno della parola template, su qualsiasi modello di sequenza :)

Scrivere la parte di infrastruttura sarà difficile (uno stack exception safe è già una sfida abbastanza difficile), ma se le astrazioni e le librerie le scrivono gli esperti, l'utilizzo poi diviene abbastanza semplice. Almeno è questo l'intento. C'è sempre un livello di complessità esposto al programmatore, ma se vuoi poter decidere l'allineamento e il layout dei dati in memoria e dettagli del genere è difficile nascondere del tutto certe cose.

Principalmete che linguaggio usi?
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 01 Maggio 2014, 06:55:05
Premetto che mi sono goduto quest'interessantissima discussione :) , c'è qualcosa che non è mi chiara.
Limitare il genericity solo ai reference object è la soluzione adottata da ISO-Modula-2, Modula-3, Oberon-2ext, Java.
E da Python, che ha soltanto reference object alla fine. D'altra parte è la soluzione più semplice.
Citazione
Ci sono due code pattern generation: lo shared object (di Ada) e specific object instantiation (di C++).

Immaginiamo di avere un generic package o template che accetta due classi con tre livelli di extension ed un tipo basic type come parametro, vengono usate per due funzioni all'interno del package/template. Classi T, T2 (estende T), T3 (estende T2), P, P1 (estende P), P2 (estende P1).


Shared object:

Il codice generato è unico per tutti i casi possibili. Vengono utilizzate le classi estese più grosse (T2 e P2) e le classi base vengono allocate con un padding tutte della stessa dimensione.
Per il parametro basic type viene usato il basic type più grande rappresentabile.

Numero totale di codice oggetto per classe: 2, numero funzioni: 2.

Vantaggi: Velocità di compilazione, easy debugging, no code bloating.

Svantaggi: Il codice delle classi occupa leggermente di più, overhead sui basic type, aritmetica lenta (gli interi vengono usati all'intero più grosso di 128 bit, i float sono tutti a precisione doppia, etc..).
Gli interi dovrebbero arrivare a 64 bit al massimo.

A parte questo dettaglio, non capisco per quale motivo per il basic type si debba utilizzare il più grande rappresentabile. Se utilizzi un basic type come parametro per il generic package, che viene usato poi in tutte le classi di cui sopra, e mettiamo che tale template venga "istanziato" usando soltanto interi a 8 e 16 bit, a conti fatti il compilatore dovrebbe utilizzare l'intero più grande utilizzato, quindi quello a 16 bit, anziché la massima rappresentazione (32 o 64 bit) per l'unica copia di dati (definiti nelle classi, come parametri dei metodi, e come variabili locali) e codice che ne fa uso.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 01 Maggio 2014, 06:56:06
Principalmete che linguaggio usi?

Questa me la chiedo anche io  ;D
Azzardo: PHP e/o Javascript. ::)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 01 Maggio 2014, 11:33:34
E da Python, che ha soltanto reference object alla fine. D'altra parte è la soluzione più semplice.

E va bene in tutti i casi. Ho visto povere argomentazioni contro questo tipo di genericity, come per esempio quando fanno vedere che le operazioni su intero/float wrappate in un object reference sono lente per via di quello che chiamano boxing/unboxing.
I container sono fatti per conservare oggetti, non per farci dei calcoli di sopra. Un buon programmatore si copia il tipo di dato in una struttura locale (o direttamente in delle variabili) se c'è una lunga computazione da fare
Assolutamente d'accordo. Con Python, comunque, non si può fare, perché non esistono tipi primitivi, ma soltanto reference a oggetti; d'altra parte non è nato pensando alle prestazioni.
Citazione
Gli interi dovrebbero arrivare a 64 bit al massimo.

Sì, hai ragione, non so per quale motivo ricordassi che GNAT supportasse 128 bit (con l'uso di due registri e 16 byte di allocazione nelle strutture). Invece l'implementazione supporta fino a 64 bit, boh.. starò tirando le cuoia :P
Ho visto che GNAT è un'implementazione di ADA. E' chiaro ed è ragionevole che se il linguaggio supporti interi a 128 o più bit il massimo intero rappresentabile non potrebbe non tenerne conto. Solo che a livello prestazionale le ricadute sarebbero tutt'altro che trascurabili.
Citazione
A parte questo dettaglio, non capisco per quale motivo per il basic type si debba utilizzare il più grande rappresentabile. Se utilizzi un basic type come parametro per il generic package, che viene usato poi in tutte le classi di cui sopra, e mettiamo che tale template venga "istanziato" usando soltanto interi a 8 e 16 bit, a conti fatti il compilatore dovrebbe utilizzare l'intero più grande utilizzato, quindi quello a 16 bit, anziché la massima rappresentazione (32 o 64 bit) per l'unica copia di dati (definiti nelle classi, come parametri dei metodi, e come variabili locali) e codice che ne fa uso.

In C++ una cosa del genere si potrebbe accettare (se solo non supportasse l'uso implicito dei template) ma in Ada no. In C++ un vero separate compilation non esiste.

I generics in Ada vengono compilati una sola volta e viene generato un unico (shared) object code per sempre. Se prima l'object code è stato generato per il basic type (più grande istanziato) a 16 bit e poi vari mesi dopo in un modulo X è stato istanziato per 32 bit, allora l'object code del generic andrebbe rigenerato e tutti i package che fanno uso del generic package andrebbero ricompilati perché cambiano tutti gli offset. Questo va contro il principio del modularity, solo la modifica dell'interfaccia del modulo implica la ricompilazione del modulo e di tutti moduli che lo utilizzano

Il modularity è un big topic, però stringendo in Ada una cosa del genere non sarebbe accettabile :-)
Ho capito, e in quest'ottica sicuramente è molto comodo l'approccio utilizzato.
Però in ottica di generazione di un binario partendo da tutti i sorgenti, preferirei un approccio più ottimizzato, che funzioni come ho descritto sopra.

Diciamo che l'approccio modularity di Ada lo posso accettare quando sto lavorando a un progetto (in modalità debug), per cui è senz'altro comodo non dover ricompilare continuamente tutto (in C e C++ la ricompilazione è overkill; beati i tempi di Turbo Pascal e Delphi), ma quando devo generare la build finale (modalità release) mi aspetto che debba essere fatto tutto il possibile per tirare fuori il meglio; SE ci sono le condizioni, ovviamente.
Citazione
Principalmete che linguaggio usi?

Questa me la chiedo anche io  ;D
Azzardo: PHP e/o Javascript. ::)

:'( :'( :'( :'(
Credo non potesse finirmi peggio
L'avevo intuito dai discorsi che avevi fatto. Purtroppo è capitato pure a me in passato. Adesso in generale programmo poco, e ho a che fare più che altro con C/C++ e Python (le rare volte che  sviluppo roba; da solo), con qualcosa di Fortran (niente sviluppo, fortunatamente).

Ti auguro di trovare di meglio, perché francamente mi sembri sprecato. Anzi, se hai voglia di cambiare aria (in tutti i sensi) e di lavorare in un ambiente di gran lunga più stimolante, fammi sapere. ;)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: cdimauro - 01 Maggio 2014, 14:13:41
Quindi con l'embedded C hanno finalmente reso onore al mito del C, che lo dipinge come un linguaggio di basso livello? Perché personalmente cosa NON apprezzo del C è il fatto che venga usato per system programming, ma non mi dà la possibilità di andare realmente a toccare certi dettagli della macchina, come ad esempio definire dei tipi interi di dimensione precisa in termini di bit, endianess, e altro che farebbe comodo nell'ottimizzazione delle istruzioni e dell'uso dei registri.

Se hanno risolto con questo embedded C, allora magari un'occhiata gliela butto (anche se la sintassi del C mi rimane comunque sullo stomaco).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: fulvio - 01 Maggio 2014, 17:55:37
Inoltre io non sono il programmatore ideale da un punto di vista dell'imprenditore, per il quale il tempo è denaro; sono molto lento: mi piace pensare alla soluzione ottimale anziché buttare lì righe di codice e aspettare che funzionino (credo sia una paranoia degli ultimi anni, più piccolo producevo di più e velocemente). Comunque i risultati si stanno vedendo a fine progetto, il mio codice funziona senza problemi e non presenta bug di funzionalità lievi/gravi; invece si sta impiegando un sacco di tempo per il bug fixing (soprattutto funzionali) nel codice di altri.
Non è un vanto, perché continuo ugualmente a reputarmi inadeguato per l'imprenditore: per me un software che richiede 6 mesi o più di sviluppo non può essere fatto in 2 mesi con poco man-power e senza una forte progettazione iniziale (semplicemente, perché non ci sono le specifiche prima, ma vengono chieste sul momento dal cliente: ciò significa che spesso non sappiamo cosa ci troviamo a sviluppare e certe decisioni iniziali sbagliate portano frustrazione dopo).

Aggiungo poi che per come fanno i colloqui, non potrei superarli. Fanno domande troppo approfondite sulle API di vari framework, io sviluppo con il manual reference davanti e con l'autocompletition dell'editor, non imparo mai nulla a memoria (e per le complessità che ha raggiunto la programmazione di oggi, sarebbe impossibile almeno per me).
Cambiare stato comunque mi alletta parecchio, prima di trovare questa occasione avevo intenzione di trasferirmi in UK, ma.. negli ultimi tempi sono cambiate tante cose e ci sono tanti punti interrogativi, si vedrà.. se devo cambiare però, qualcosa che non abbia a che fare con l'informatica :-)

Devo dire che anche io ho lo stesso modo di programmare. D'altronde le possibilità sono due: o ti specializzi in un prodotto e speri che non scompaia dal mercato in poco tempo, o impari i fondamenti e alla fine ti trovi a tuo agio con tutto, magari dovrai chiedere come fare una certa cosa, ma almeno non ti mancheranno le domande e qualcuno che sa a memoria il reference manual di qualcosa lo trovi sempre :P

Io adesso sono in UK, con un coinquilino siciliano per giunta (che però lavora in finance). In fin dei conti non si sta male, ma venendo anch'io dal SUD (provincia di Napoli) ho sempre da lamentarmi del tempo e del cibo. E purtroppo anche quelle volte che si raggiungono i 28/30 gradi, non hai proprio l'opzione di andare al mare (ovviamente c'è a Brighton per esempio, ma non è niente di lontanamente comparabile  :()
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: fulvio - 01 Maggio 2014, 20:33:12
Io adesso sono in UK

Credo che tra qualche anno gli italiani saranno circa il 30-40% della popolazione inglese :D che lavoro fai lì?


Eheh mi sa che ci siamo già vicini, in pratica alcuni italiani vivono qui da anni senza aver imparato una parola di inglese. Io al momento lavoro in una piccola software house che fa principalmente software di catalogazione principalmente orientate ai musei e librerie, ma abbiamo anche sistemi di catalogazione di asset digitali (anche customizzati, alcune forze di polizia lo utilizzano qui). Ma è stato il primo lavoro che ho trovato in attesa di migliorare la lingua. Tra poco mi guardo intorno, qui di opportunità nel nostro campo ce ne sono a bizzeffe, dalle piccole alle grosse società ;)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 01 Maggio 2014, 21:41:17
I container sono fatti per conservare oggetti, non per farci dei calcoli di sopra. Un buon programmatore si copia il tipo di dato in una struttura locale (o direttamente in delle variabili) se c'è una lunga computazione da fare

Però devi avere il programmatore bravo! :P
A parte gli scherzi, quella idea va bene finché devi prendere un valore ogni tanto e farci tanti conti, meno quando devi lavorare su tantissimi dati e dei fare poche elaborazioni per ognuno.

Una cosa che proprio non sopporto del Java è proprio l'inefficienza di memoria (sopratutto visto che lo uso per scrivere programmi su Android): per esempio tempo fa stavo sviluppando una piccola app insieme ad altre persone*, e mi serviva tornare da una funzione due valori, un float e un int.

In C++ avrei scritto std::pair<float, int>, in Java ho fatto Pair<Float, Integer> (mi sembra che Pair sia una cosa fornita da Android).

Analizziamo le due soluzioni: in C++ la struttura occupa esattamente 1 float e 1 intero, quindi il assolutamente il minimo. In Java hai:
- Un oggetto Float, che consiste in un float, più i dati per il garbage collector e il lock che ogni oggetto Java si porta dietro;
- Un oggetto Integer, che ha un int, più il garbage collector etc.
- Un oggetto Pair, che contiene un puntatore riferimento a Float e uno a Integer, più i dati del GC etc.
- Il riferimento verso Pair effettivamente ritornato dalla funzione.
Tra una cosa e l'altra ci saranno almeno 32 byte usati in tutto per qualcosa che contiene 8 byte di dati.
In più l'accesso ai campi della pair in C++ è "banale", mentre il Java non ti permette di fare tante conversioni automatiche tra il valore boxato e il valore nativo, aumentato l'irritazione del programmatore (i.e. io).

Pensa ora se dovessi creare un ArrayList di queste piccole strutture: sarebbe un array di riferimenti , quindi la dimensione totale sarebbe lunghezzaArray*(dimensionePair&Co + dimensioneRiferimento), che quindi sarebbe qualcosa tipo lunghezza*36.
In C++ posso creare un std::vector<> di quei std::pair, e la memoria occupata sarà esattamente lunghezza*(sizeof(float) + sizeof(int)) = lunghezza*8 (tipicamente).
In più il vector<> garantisce che gli elementi siano consecutivi in memoria, quindi posso fornire il puntatore a un'API C come ad esempio OpenGL.


* Era un progetto dell'università, quindi dovevo lavorare con gente estremamente inesperta; ti risparmio il raccontarti di come il programma consumava così tanta memoria (se non fosse abbastanza già di suo doveva lavorare su immagini abbastanza grandi!) che non partiva nemmeno nel mio LG Optimus Dual da 512 MB di RAM; a loro funzionava solo perchè avevano tutti cellulari nuovissimi con 2+ GB oppure perchè giravano sul simulatore; son dovuto andare in giro per il codice a togliere e =null tanti di quei riferimenti solo per permettere al GC di girare.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 01 Maggio 2014, 22:10:35
@Z80Fan:
Java consuma tanta RAM, ma nel caso di Android c'è anche l'Heap di Dalvik limitato a 32MB per processo/Activity nei cellulari vecchi e 64 o 128MB in quelli nuovi.
Comunque a me non dispiace il Java perchè mi permette di scrivere codice molto velocemente, mantenendo comunque una buona organizzazione. Chiaramente non è il miglior linguaggio e ha tanti difetti, ma la comodità che si porta dietro è fondamentale quando devi lavorare in tempi molto stretti. Per fare analisi d'immagini puoi sempre scrivere il tuo algoritmo in un linguaggio nativo come il C++ e poi chiamarle le sue funzioni da Java tramite JNI (in Android c'è un tool già pronto in "Android NDK" per integrare classi C++ e Java).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 01 Maggio 2014, 23:00:24
@Z80Fan:
Java consuma tanta RAM, ma nel caso di Android c'è anche l'Heap di Dalvik limitato a 32MB per processo/Activity nei cellulari vecchi e 64 o 128MB in quelli nuovi.

Esatto. In realtà Android promette almeno solo 16 MB, anche se la maggioranza ne ha molti di più (sul mio LG sono 48) e solo dispositivi molto vecchi scendono sotto i 24.

Comunque a me non dispiace il Java perchè mi permette di scrivere codice molto velocemente, mantenendo comunque una buona organizzazione. Chiaramente non è il miglior linguaggio e ha tanti difetti, ma la comodità che si porta dietro è fondamentale quando devi lavorare in tempi molto stretti.

Io non so come fai; ogni volta che devo fare qualcosa mi scontro con qualche piccola idiozia che mi costringe a girarci intorno o a rendere il codice meno efficiente; non parliamo poi di Android che ha delle API insulse e contorte, con pure documentazione di scarsa qualità e esempi sbagliati.

Cerco sempre di farmi piacere Java (visto che mi tocca usarlo), ma ogni volta che programmo ho sempre una sensazione di pesantezza, di dover scrivere nel modo che vuole il compilatore piuttosto che nel modo che mi sembra più logico a me. :(

Dai, come prossimo telefono mi comprerò il Jolla, che si programma in C++ e Qt. ;D

Per fare analisi d'immagini puoi sempre scrivere il tuo algoritmo in un linguaggio nativo come il C++ e poi chiamarle le sue funzioni da Java tramite JNI (in Android c'è un tool già pronto in "Android NDK" per integrare classi C++ e Java).

Ma infatti è quello che avrei fatto io; lasciamo perdere quella storia che se dovessi raccontarvi tutto il fail che c'è stato in quel progetto non basterebbero 10 pagine. ::)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: clros - 01 Maggio 2014, 23:29:41

Dai, come prossimo telefono mi comprerò il Jolla, che si programma in C++ e Qt. ;D


OT
Ma usare C# e XAML invece? ;)
/OT
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 02 Maggio 2014, 00:39:36
@Z80Fan: con il tempo e l'esperienza impari a distoglierti dalle questioni di "accademia" ed a concentrarti sui clienti e le loro scadenze. Per quanto interessanti e importanti certi argomenti diventano solo un "dettaglio tecnico" trascurabile e irrilevante, quello che conta è fatturare :D
Chiaramente questo se sceglierai di fare lo sviluppatore professionista. Se invece ti butti in campi diversi magari puoi cercare di mantenere un livello più alto, o magari sempre nel campo professionale ma in qualche fortunata azienda che ha grandi budget e punta alla qualità del software (sono molto rare ma esistono).
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 02 Maggio 2014, 01:33:51
@Z80Fan: con il tempo e l'esperienza impari a distoglierti dalle questioni di "accademia" ed a concentrarti sui clienti e le loro scadenze.

Infatti proprio per questo Java mi sta stretto: perdo tempo a combattere con il linguaggio più scrivere il programma in modo logico; anche solo delle puttanate tipo dover fare .equals invece che == su delle stringhe per dire.

Il conto dei byte di memoria non era collegato all'altra frase sulla praticità di programmazione; il discorso del progettino fallito è più complesso, anche se farebbe un'interessante storiella: in 3 mesi avremmo dovuto fare un'applicazione completa e forse rilasciabile sul market, scadenza completamente mancata visto che quasi non c'erano le funzionalità base. I motivi del fallimento son stati tanti: la lentezza di partenza, la difficoltà di amministrare una ventina di persone con 0 esperienza, obiettivi fin troppo grandiosi etc.

Alla fine però ho ricevuto un ottimo voto, quindi non mi lamento più di tanto! ;D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 02 Maggio 2014, 01:34:56
Stai però confrontando due cose totalmente diverse, Java è un linguaggio platform independent mentre C++ è multiplatform e tendente a generare codice (spesso inutilmente e scomodamente) ottimizzato.
Dovresti confrontare quella tipologia di genericity con un linguaggio simile

Infatti sarebbe interessante vedere gli altri linguaggi se riescono a essere più efficienti in termini di memoria, anche se non dubito che Java sia il peggiore in questo ambito. ::)
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: TheKaneB - 02 Maggio 2014, 15:09:25
@Z80Fan:
tu sicuramente, per quello che vedo dai tuoi progetti personali, hai una preparazione molto superiore alla media del tipico studente universitario e non mi stupisce la difficoltà che hai avuto in un team di 20 "caproni" :D
Però ti posso assicurare che in un ambiente di programmatori esperti, un progetto Java impiega metà del tempo di sviluppo e con meno bug rispetto ad un equivalente progetto C++, e una volta acquisita la giusta esperienza con il linguaggio non ci devi più combattere :)
Questo accade facendo qualsiasi switch da linguaggio A a linguaggio B, anch'io nei primi tempi cercavo di scrivere C++ "in Java", tirando bestemmioni epici, poi ho imparato la mentalità Java e sono diventato 3 volte più produttivo.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 02 Maggio 2014, 16:17:54
Però ti posso assicurare che in un ambiente di programmatori esperti, un progetto Java impiega metà del tempo di sviluppo e con meno bug rispetto ad un equivalente progetto C++, e una volta acquisita la giusta esperienza con il linguaggio non ci devi più combattere :)
Questo accade facendo qualsiasi switch da linguaggio A a linguaggio B, anch'io nei primi tempi cercavo di scrivere C++ "in Java", tirando bestemmioni epici, poi ho imparato la mentalità Java e sono diventato 3 volte più produttivo.

Mi fido. :)

Non ho motivi "religiosi" per cui odiare Java, ho tutto l'interesse a farmelo piacere in modo da programmare meglio queste piattaforme che son sempre più importanti. :D
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 03 Maggio 2014, 18:52:29
@dsar
Lo uso perchè mi ci trovo bene, per quello che ci devo fare. Magari te lo odi ma io no.

Io non ho detto che il C++ è un linguaggio perfetto, e mi sembra che ti abbia anche spiegato vari punti che toglierei/sistemerei se fossi io a dirigere il linguaggio, e non ho neanche detto che il resto dei linguaggi sia una merda. (Ovviamente ci sono alcuni linguaggi che oggettivamente e sopra ogni forma di dubbio sono una merda, come PHP e Objective-C :P)

Non uso neanche il C++ per qualsiasi cosa: C++ per codice ad alte/altissime prestazioni e per cose a relativo basso livello, Java su Android1, Lua come scripting sopra un motore C++, Python+Web.py per siti web etc.

Non ho detto che mi piace SOLO il C++ e tutto il resto è uno schifo (come molti dicono, sopratutto programmatori C), anzi, son sempre contento di vedere come funzionano altri linguaggi e come implementano cose.

Però, per quello che programmo tipicamente, ovvero cose di basso livello oppure che richiedono alte prestazioni, la mia scelta principale rimane sempre il C++ sia perchè lo conosco già, sia perchè mi permette di scrivere codice leggibile2 e efficiente3, sia (sopratutto) perchè è supportato praticamente da un po' tutti; come si diceva, è molto più facile trovare un compilatore C++ in ambito embedded rispetto a uno ADA, Modula etc. Allo stesso modo, la compatibilità con codice e librerie C viene molto comoda quando devo interfacciarmi con tali librerie, tipo OpenGL.

Ma se devo scrivere un sito web, non lo scrivo in C++, uso Python (o PHP se proprio mi tocca); se ho bisogno di parsare dei file di testo per estrarre e/o riformattare dei valori, non uso il C++, uso qualche linguaggio di scripting fatto apposta per questo, etc.

Il mio linguaggio ideale prende sicuramente tanto dal C++, ma lo semplifica e espande in altre cose; avevo già cominciato a scrivere molte idee che inserirei in questo linguaggio: principalmente riguardavano la semplificazione della sintassi (la si rendeva un po' meno ambigua e un po' più facile da parsare, ma nessuna rivoluzione), la semplificazione nel creare template e/o fare elaborazioni a compile time (introducevo uno static if come il D e qualche altro dettaglio), miglioravo l'uso di bitfield e la specifica più precisa di strutture dati in memoria a livello di bit (importantissimo se si lavora a basso livello; allo stesso modo specificavo dimensioni esatte per i tipi base di dato come fa Java), e introducevo veri moduli software (per rimuovere l'inclusione testuale).
Se vi interessa apro un thread così vi mostro le idee. :)

Però anche se mi creassi il mio linguaggio perfetto, poi lo potrei usare solo io perchè non è supportato da nessuna parte; al massimo potrei scrivere un front-end per LLVM ma sarei lo stesso limitato alle architetture supportate da quest'ultimo.


1. Il fatto che Java non mi sta proprio a genio è anche questo: è un linguaggio staticamente e fortemente tipizzato che riprende la sintassi (e le limitazioni) da linguaggi di medio-alto livello come C e C++, eppure senza le prestazioni e con gran uso di memoria; a questo punto preferirei tanto di più usare un linguaggio più semplice e pratico come Python.

2. per leggibile intendo poter scrivere delle classi o funzioni e usarle in modo naturale; ad esempio con la ridefinizione degli operatori posso avere una classe vettore (std::vector) che si usa come un vettore nativo (con i []), oppure classi numeriche che usano i +/- etc.

3. Efficienza sia nello spazio che nel tempo, importanti sopratutto quando si elaborano grandi quantità di dati oppure le risorse hardware sono limitate.
Titolo: Re:VC++ Implementation of Switch Statement
Inserito da: Z80Fan - 03 Maggio 2014, 19:59:40
certo che si  ;D

anche se … non ti offendere, ma sei di due spanne oltre i miei limiti, ti ricordo che ho gia' sputato l'anima per cavar fuori e far pedalare l'interprete bovino, e ora di farlo evolvere … mi sa che vengon fuori cose suine se non equine (o ancora + equivoche con la maestrina)

Dubito che verrà mai fuori un'implementazione: è una bella quantità di lavoro per far il tutto; io sicuramente non ne ho il tempo in questo periodo o nell'immediato futuro.
Per me già solo la discussione soddisfa. ;D