Quali sono i vantaggi del passare per valore?

3

Ho sempre pensato che passare per valore è un retaggio delle prime lingue, perché i designer non avevano mai visto nient'altro . Ma dopo aver visto i nuovi linguaggi come Go adattare lo stesso principio mi ha confuso.

L'unico vantaggio a cui riesco a pensare è che ti assicuri che il valore che stai passando non venga modificato. Ma ogni volta che devi passare una grande struttura a una funzione, devi passare il puntatore (o riferimento) per impedire la copia, se la lingua lo consente.

Per impedire la modifica dei parametri, potrebbe essere introdotto un meccanismo const ness invece di far passare l'intera lingua per valore.

Ho fatto il codice per anni e raramente ho dovuto passare per valore. Quasi sempre, non ho bisogno che il mio valore / oggetto venga copiato in una chiamata di funzione; e spesso non ho bisogno che sia modificato all'interno della funzione *.

Qual è la motivazione alla base del passaggio delle lingue moderne per valore? Ci sono dei vantaggi di cui non sono a conoscenza?

Modifica: quando dico passare per valore, non intendo le primitive. Sono facili ed economici per passare di valore. Il mio obiettivo principale sono gli oggetti o le strutture che consistono in più di 1 primitivo e quindi costoso da copiare.

*: ho chiesto in giro e altri hanno riportato qualcosa di simile con il loro uso dei parametri.

    
posta nimcap 22.02.2014 - 20:46
fonte

3 risposte

11

Pass-by-reference rende alcune cose più efficienti e consente di aggiornare i parametri all'interno delle subroutine, ma non è affatto una panacea.

Immagina un'applicazione parallela. Quando si utilizza il riferimento pass-by, è necessario un meccanismo di blocco per mantenere uno stato normale. Il pass-by-value non ha questa limitazione. Ho visto programmi multi-thread che trascorrono più tempo in attesa di mutex rispetto all'elaborazione dei dati. Qui il pass-by-value può essere un grande guadagno in termini di efficienza.

Immagina un'applicazione distribuita. Questo è sempre un valore pass-by, perché il sistema remoto ha bisogno della propria copia dell'oggetto. Il pass-by-reference deve essere simulato usando oggetti proxy. Richiede un extra overhead di rete per mantenere sincronizzati gli oggetti proxy. Qui il valore pass-by salva non solo il tempo di elaborazione, ma riduce la larghezza di banda della rete.

    
risposta data 23.02.2014 - 20:32
fonte
6

Il passaggio per valore è solo un corollario per valutare la semantica (vale a dire le variabili di valore, i membri dell'oggetto, ecc.). A parte il vantaggio che dici, questo aggiunge:

  • Aggregati molto efficienti. Un tipo come struct Foo { T a; U b; } non richiede un'assegnazione separata o un'indirizzamento extra per i membri.
  • Astrazioni a costo zero: class IntWithDifferentBehavior { int value; ... } è esattamente efficiente quanto int , assumendo l'invio statico per i metodi.
  • Va molto bene con il monitoraggio della proprietà e della durata. Una conseguenza è il supporto alla distruzione deterministica, che consente a RAII di essere un'alternativa alla (semi) gestione manuale delle risorse.

Inoltre, il pass-by-value è molto più facile da rendere la memoria sicura ed efficiente. Se si passano i puntatori / riferimenti alla memoria allocata nello stack, è necessario assicurarsi che la memoria sopravviva al riferimento. Se invece utilizzi la gestione automatica della memoria per assicurarti che, paghi un prezzo di runtime per questo.

    
risposta data 22.02.2014 - 21:41
fonte
1

I always thought pass by value is a legacy from the early languages, because the designers had never seen anything else.

Questa è una caratterizzazione fittizia per due aspetti:

  1. Questo (tipo di) presuppone che il pass-by-value sia la forma originale di passaggio e che sia stato sostituito da cose migliori. In effetti, la cronologia dimostra chiaramente che questo non è vero (come la risposta che hai citato come fonte).

  2. Implica (senza alcun argomento logico o supporto) che i progettisti dei linguaggi di programmazione tradizionali siano ignoranti della storia del linguaggio di programmazione. Una corretta revisione della documentazione pertinente rivelerà che questa nozione è completamente falsa ... per non parlare di insulti alle persone coinvolte.

La decisione effettiva di supportare pass-by-reference, pass-by-value e / o una delle forme più oscure / storiche (come la copia pass-by o il nome pass-by) è strongmente intrecciata con altre aspetti del design generale della lingua ... e motivati dagli obiettivi del design.

Ad esempio:

  • L'obiettivo è fornire una lingua in cui i programmi siano facili da leggere e comprendere?

  • L'obiettivo è fornire un linguaggio che massimizzi il "potere espressivo" o "concisione"?

  • L'obiettivo è fornire un linguaggio che massimizzi le "prestazioni" su determinati tipi di problemi?

  • L'obiettivo è supportare un particolare "paradigma" di programmazione rispetto ad altri; per esempio. procedurale, OO, funzionale, puro funzionale, parallelo / concorrente?

E così via.

In breve, sono andati ben oltre il pensiero semplicistico come "i vantaggi del passaggio per valore".

I have been coding for years and I rarely needed to pass by value. Almost always, I don't need my value/object to be copied to a function call.

Qualcosa non ha senso con questo ...

Se hai codificato per anni in Java, C, C ++, C # o nella maggior parte degli altri linguaggi di programmazione moderni, sei stato utilizzando passaggio per valore la maggior parte del tempo. È il modo predefinito di fare le cose ... e in alcune lingue (come Java) è l'unico modo.

Ad esempio

    int i = 1;
    myFunction(i);

AFAIK, i sarà passato per valore in C, C ++, Java e C #. Se vuoi passare per riferimento (in C e C ++) devi scriverlo esplicitamente; per es.

    myOtherFunction(&i);

In in realtà fai sempre questo nel tuo codice? Per variabili primitive tipizzate? Io non la penso così

    
risposta data 23.02.2014 - 03:27
fonte

Leggi altre domande sui tag