Le implicazioni delle prestazioni dell'utilizzo di push contro concat in grandi array derivano principalmente dai diversi modi in cui questi metodi gestiscono la fusione dell'array o l'aggiunta di elementi, nonché la loro gestione della memoria sottostante e le spese generali computazionali.
Quando si utilizza Array.Push, gli elementi di un array vengono aggiunti direttamente all'array esistente. Per la fusione di array, questo comporta spesso uno schema come l'uso dell'operatore Appliche o Spread per spingere più elementi contemporaneamente - ad esempio, array.prototype.push.apply (arr1, arr2). Questo approccio modifica l'array originale in atto e generalmente si comporta in tempo lineare, O (n), dove n è il numero di elementi che vengono spinti. Il motivo è che Push in genere aggiunge elementi alla fine dell'array esistente senza creare un nuovo array o copiare ripetutamente l'intero contenuto. A causa di questa mutazione sul posto, il sovraccarico di memoria è ridotto al minimo e il metodo sfrutta spesso blocchi di memoria contigui ottimizzati e la località della cache, riducendo il costo dell'accesso alla memoria.
Al contrario, Array.Concat non modifica gli array originali. Invece, crea un nuovo array che contiene gli elementi degli array originali concatenati insieme. La creazione di questo nuovo array prevede l'assegnazione della memoria per la dimensione combinata degli array e la copia di elementi da entrambi gli array di origine in questo spazio appena assegnato. Questa copia introduce un sovraccarico generalmente proporzionale alle dimensioni di entrambi gli array, rendendo la complessità temporale dell'operazione O (M + N), dove M e N sono le dimensioni delle array concatenate. La creazione di un nuovo array e la copia dei dati comporta un aumento dell'utilizzo della memoria e una maggiore probabilità di innescare la raccolta della spazzatura, in particolare evidente con array molto grandi.
I test di riferimento mostrano costantemente che la push può essere significativamente più veloce di una concat per le operazioni che comportano la fusione o l'aggiunta di un gran numero di elementi. Ad esempio, un punto di riferimento ha dimostrato che per la fusione di array con migliaia di elementi ripetutamente, la spinta era circa 945 volte più veloce di Concat in Chrome e persino più veloce in Firefox. Questa grande differenza proviene dal comportamento di Concat nella creazione di un nuovo array e dalla copia di dati ripetutamente, mentre Push cresce l'array esistente in modo più incrementale e in posizione, evitando ripetute riallocazioni della memoria.
Tuttavia, queste caratteristiche di prestazione possono variare a seconda degli scenari di utilizzo. Se l'obiettivo è una singola concatenazione di due array pre-allocati molto grandi, Concat potrebbe funzionare relativamente bene poiché si alloca una volta e fa la copia una volta. In tali casi, l'approccio a uno per uno o batch di Push potrebbe causare riallocazioni multiple o copiare internamente, il che potrebbe ridurre il suo vantaggio teorico. Tuttavia, per la fusione ripetuta o l'aggiunta di molti elementi in molti array, Push tende ad essere ammortizzata O (1) per aggiunta perché gli array spesso allocano la memoria geometricamente (raddoppiando la capacità quando superati), rendendola altamente efficiente nel complesso.
Dal punto di vista della memoria, la mutazione sul posto di Push significa allocazioni meno frequenti e potenzialmente meno sforzo sul sottosistema di memoria. Il metodo CONCAT, che richiede nuove allocazioni e copie di nuovo su di nuovo, sottolinea la memoria e cache di più, specialmente per grandi array. Questa situazione si traduce in operazioni CONCAT che potrebbero superare i limiti della cache della CPU, portando a tempi di accesso alla memoria più lenti a causa del recupero di dati da cache più elevate o memoria principale ripetutamente. Push, evitando le rivisite sui dati già nell'array, può sfruttare meglio la località della cache.
Va notato che Push altera l'array originale mentre Concat conserva l'immutabilità restituendo un nuovo array. Questa differenza è importante nella progettazione dell'applicazione ma influisce anche sulle prestazioni. Concatenazioni immutabili con concat non garantiscono effetti collaterali ma pagano il prezzo della memoria extra e della copia, mentre la spinta scambia l'immutabilità per la velocità modificando direttamente l'array di origine.
Alcune sfumature includono che i motori JavaScript potrebbero ottimizzare queste operazioni in modo diverso in base al contesto e alla complessità. Ad esempio, i motori ottimizzano tipi fissi o piccoli array in modo più aggressivo. Inoltre, la firma del metodo di Concat supporta l'apprendimento di più array e valori contemporaneamente (firme sovraccaricate), che richiedono fasi di appiattimento interno e copia che aggiungono sovraccarico, mentre la spinta aggiunge in modo diretto elementi senza tale appiattimento.
Per quanto riguarda la raccolta della spazzatura, le frequenti allocazioni coinvolte in Concat possono aumentare il carico di lavoro della raccolta della spazzatura perché i vecchi array vengono scartati dopo la copia. Ciò può portare a pause o cadute di prestazioni in scenari ad alte allocazioni. La coltivazione di Push un array esistente riduce la frequenza delle allocazioni e quindi la raccolta della spazzatura in alto.
Nel complesso, la scelta tra Push e Concat comporta un compromesso tra velocità (push) e immutabilità/convenienza (Concat). Per le operazioni su grandi array con prestazioni come priorità, la spinta è generalmente il metodo preferibile a causa della sua più efficiente gestione della memoria e delle spese generali inferiori. Il sovraccarico di CONCAT dalla creazione e dalla copia dell'array diventa molto costoso all'aumentare delle dimensioni dell'array. Negli scenari in cui l'immutabilità è fondamentale, la concat viene utilizzata nonostante la penalità delle prestazioni.
In sintesi, PUSH in genere presenta prestazioni migliori e sovraccarichi di memoria più bassi rispetto a Concat nel contesto di grandi array a causa della modifica sul posto, ammortizzare le aggiunte a tempo costante e una ridotta copia. Concat soffre di ulteriori allocazioni di memoria e di costi di copia perché crea un nuovo array ogni volta che viene chiamato, che colpisce sia il tempo impiegato che l'utilizzo della memoria, in particolare con array molto grandi. Queste differenze sono ingrandite quando si uniscono molti array o si tratta di set di dati enormi, dove la spinta può essere centinaia di migliaia di volte più veloce di Concat secondo i parametri di riferimento. Tuttavia, a seconda del contesto di utilizzo e delle ottimizzazioni del motore, questi modelli generali possono avere eccezioni e dovrebbero essere considerati insieme alla necessità di immutabilità e manutenibilità del codice.