Oggetti o primitive come argomenti

1

Mi sono imbattuto nel termine "smaltimento dei rifiuti" e ora sono preoccupato di consumare troppa memoria. Apparentemente (correggimi se sbaglio) ogni volta che viene creato un oggetto, la memoria è riservata per esso e quell'oggetto deve essere correttamente smaltito se non più necessario. La mia domanda è se uno dovrebbe evitare di istanziare gli oggetti, quando possibile. Ad esempio, se una funzione richiede una coordinata come argomenti, dovrei avere

example(int x,int y)

o va bene avere

example(Point p)

e durante la chiamata effettiva faccio qualcosa di simile

example(new Point(5,5));

Sono preoccupato di non rallentare l'applicazione, quindi mi piacerebbe sapere se avere le primitive come argomenti è meglio che avere oggetti che di solito verranno istanziati sul posto

    
posta Abbrew 25.03.2015 - 06:33
fonte

2 risposte

6

now I'm worried about using up too much memory

Non stai parlando di un vero programma, ma solo di una "sensazione" che i tuoi programmi potrebbero consumare troppa memoria? Perché? Poni questa domanda quando hai scritto un programma che usa troppa memoria, non in anticipo.

My question is if one should avoid instantiating objects then whenever possible

Risposta breve: no , non "quando possibile", non "molte volte", forse "in alcuni rari casi". La decisione di creare classi e oggetti dovrebbe essere guidata prima e quasi dalla domanda se formano astrazioni appropriate per il tuo compito o algoritmo. Prestazioni o ottimizzazioni della memoria a quel livello che hai in mente dovrebbero essere fatte quando necessario, mai prima.

should I have example(int x,int y) or is it okay to have example(Point p)

In realtà, quell'esempio potrebbe essere un po 'fuorviante, poiché porterà a chiamate

 example(new Point(5,5))

vs.

 example(5,5)

e quest'ultimo sembra più leggibile del primo a prima vista. In un programma del mondo reale, tuttavia, probabilmente non dovrai scrivere qualcosa come example(new Point(5,5)) troppo spesso, invece devi elaborare una serie di punti in un modo come questo:

foreach(Point p in setOfPoints)
   example(p);

che è più completo di example(p.X,p.Y) . E se hai davvero molte chiamate con valori letterali hard-encoded come example(new Point(5,5)) , potresti fornire entrambe le varianti example come zucchero sintattico. Nota che la domanda principale qui è "cosa rende il programma più leggibile?", Non "questo fa una leggera differenza nell'uso della memoria a livello di micro scala?".

Immagina cosa succede se hai molte funzioni con più di un parametro Point , come

 bool doPointsFormATriangle(Point p1, Point p2, point p3)

vs

 bool doPointsFormATriangle(double x1, double y1, double x2, double y2,double x3, double y3)

ottieni il doppio del numero di parametri nel secondo caso e la leggibilità delle chiamate a quella funzione diminuisce dello stesso fattore di due.

In effetti, dove lavoro, devo ancora mantenere alcuni vecchi programmi scritti da un ragazzo principiante alcuni anni fa nello stile come il secondo doPointsFormATriangle , con centinaia di chiamate di funzioni che passano tutti i punti 3D come coordinate primitive. Da quell'esperienza posso dirti che è orribile - quindi fai un favore a te stesso ed evita quello stile.

    
risposta data 25.03.2015 - 08:08
fonte
6

Dipende davvero dal linguaggio di programmazione e dall'implementazione. Leggi anche il libro di Scott su Pragmatica del linguaggio di programmazione .

Leggi il wikipage su Garbage Collection (GC). GC può essere abbastanza efficiente, leggi A.Applicare il vecchio articolo: Garbage Collection può essere più veloce dello Stack Assegnazione e per una buona panoramica del manuale GC

Alcuni linguaggi di programmazione, come C , non hanno nemmeno oggetti e richiedono memoria manuale gestione, leggi ulteriori informazioni su allocazione della memoria dinamica C .

C ++ è leggermente migliore, in particolare perché ha idiomi di programmazione come RAII e per via dei suoi distruttori ( implicitamente chiamato alla fine del blocco).

Java è compilato per JVM bytecode che generalmente ha un buon GC.

I linguaggi funzionali come le implementazioni Ocaml, SML, Haskell, Common Lisp (e la maggior parte delle JVM) di solito hanno un buon GC generazionale che gestisce valori o oggetti nuovi e più vecchi.

Durante la codifica, preferisce codice leggibile e gestibile e algoritmi efficienti . Ricorda l'adagio che l'ottimizzazione prematura è male (il compilatore è l'ottimizzazione abbastanza bene, e potrebbe persino ottimizza example(new Point(x,y)) come example(x,y) in alcuni casi). Se davvero ti interessa, profila e confronta la tua applicazione, quindi metti i tuoi sforzi di ricodifica su piccoli punti caldi. Non preoccuparti!

    
risposta data 25.03.2015 - 06:37
fonte

Leggi altre domande sui tag