Ci sono dei compromessi in ogni scelta di design.
Quando hai un linguaggio OO "puro" (vedi se puoi convincere qualcuno a concordare su quel che è) , quando Inoltre, piuttosto che avere il sistema ottenere due numeri e aggiungerli, si sta invece invocando dapprima il metodo add
sull'oggetto e recuperandone uno nuovo (rendendo possibile la creazione di oggetti numerici mutabili per tempi difficili).
Un esempio di questo sarebbe la classe BigInteger . Invece di int fourtyTwo = 6 * 7;
hai BigInteger fourtyTwo = new BigInteger(6).multiply(new BigInteger(7));
Hai creato un totale di tre oggetti e fatto alcuni calcoli in background. Anche questo è un po 'un casino, ma questa è solo la semantica - puoi nasconderlo con gli operatori, ma è ancora che fa tutto il lavoro dietro di esso.
Da C2 È orientato agli oggetti Java il motivo diventa chiaro:
Lastly, it is a hybrid to provide performance gains. Even though Smalltalk has an advanced virtual machine, its inability (when I was using it) to provide a machine-correlated bytecode for integer math placed a significant performance impact on its entire environment. Being a hybrid, Java cannot be called a true Object-Oriented language. But then, why does it matter? ;-) Use the right tool for the job and life will be happy!
Puoi vedere ciò che viene menzionato in alcuni documenti per SmallTalk:
Thus, math is not a special case in Smalltalk; it is done, exactly like everything else, by creating objects, and sending them messages. This may seem odd to the Smalltalk novice, but this regularity turns out to be quite a boon: once you've mastered just a few paradigms, all of the language “falls into place”. Before you go on to the next chapter, make sure you try math involving * (multiplication), - (subtraction), and / (division) also. These examples should get you started:
Mentre sì, gli uomini sanno che alcune cose possono essere più eleganti nel design del linguaggio, ma significa anche che sarà più lento. Da talk su SmallTalk e Objective C :
What makes things slow?
- Small integer arithmetic
- Boxing
- Dynamic message lookup
- Memory management operations
Un altro esempio di questa performance può essere visto su Language Benchmarks Game per Ruby vs Java - dove Ruby implementa la" pura "matematica stile OO - i messaggi vengono inviati all'oggetto da aggiungere anziché lavorare con le primitive. Nota che in molti casi Ruby è uno o due ordini di grandezza più lento di Java. Questi benchmark pesano tutti sulla matematica e, guardando il codice Java, usano tutti i primitivi.
Ci sono cose che puoi fare per accelerare, ma è ancora meno che ottimale. L'inizio di Java era afflitto da problemi di prestazioni. Fare matematica molto più lentamente sarebbe stato terribile.
Osserviamo un'architettura Java ad alte prestazioni: LMAX . È stato tirato fuori da ogni immaginazione, in alcuni casi, riscrivendo alcune cose di base.
It took a bit more cleverness to go up another order of magnitude. There are several things that the LMAX team found helpful to get there. One was to write custom implementations of the java collections that were designed to be cache-friendly and careful with garbage. An example of this is using primitive java longs as hashmap keys with a specially written array backed Map implementation (LongToObjectHashMap). In general they've found that choice of data structures often makes a big difference, Most programmers just grab whatever List they used last time rather than thinking which implementation is the right one for this context.
Scrittura di una HashMap che potrebbe funzionare su <long, Object>
anziché su% co_de consentita per alcuni significativi guadagni in termini di prestazioni non dovendo fare l'uguaglianza basata su oggetti per due oggetti (potrebbe solo usare <Long, Object>
) ed evitare un numero di problemi con garbage collection (guarda il tuo heap un po 'di tempo e conta quanti oggetti ==
sono seduti quando usi pesantemente Long
s).
Infine, considera che l'hotspot optimizer di Java compilerà il codice su nativo quando necessario. Il codice prodotto da HashMap
è molto più semplice e più veloce del corrispondente int fourtyTwo = 6 * 7
Si tratta di trade offs, e questo è stato uno dei punti in cui la performance ha conquistato la "pura" eleganza.