Implicațiile de performanță ale utilizării push versus concat în tablouri mari apar în primul rând din diferitele moduri în care aceste metode gestionează fuziunea sau adăugarea elementelor, precum și gestionarea lor de memorie de bază și cheltuielile de calcul ale acestora.
Când utilizați Array.push, elementele dintr -un tablou sunt anexate direct la tabloul existent. Pentru fuzionarea tablourilor, acest lucru implică adesea un model precum utilizarea aplicatorului sau a operatorului de răspândire pentru a împinge mai multe elemente simultan, de exemplu, array.prototype.push.apply (arr1, arr2). Această abordare modifică tabloul original în loc și, în general, funcționează în timp liniar, o (n), unde n este numărul de elemente care sunt împinse. Motivul este că Push apară de obicei elemente la sfârșitul tabloului existent, fără a crea un nou tablou sau a copia întregul conținut în mod repetat. Datorită acestei mutații în loc, memoria generală este redusă la minimum, iar metoda exploatează adesea blocuri de memorie contigue optimizate și localitate de memorie cache, reducând costul accesului la memorie.
În schimb, array.concat nu modifică tablourile originale. În schimb, creează un nou tablou care conține elementele tablourilor originale concatenate împreună. Crearea acestui nou tablou implică alocarea memoriei pentru dimensiunea combinată a tablourilor și copierea elementelor din ambele tablouri sursă în acest spațiu nou alocat. Această copiere introduce un aerian care este în general proporțional cu dimensiunea ambelor tablouri, ceea ce face ca complexitatea timpului O (M + N), unde M și N sunt dimensiunile tablourilor sunt concatenate. Crearea unui nou tablou și a datelor de copiere are ca rezultat utilizarea crescută a memoriei și o probabilitate mai mare de declanșare a colectării gunoiului, mai ales vizibile cu tablouri foarte mari.
Testele de referință arată în mod constant că push poate fi semnificativ mai rapid decât concat pentru operațiunile care implică fuziunea sau adăugarea unui număr mare de elemente. De exemplu, un referință a demonstrat că, pentru contopirea tablourilor cu mii de elemente în mod repetat, împingerea a fost de aproximativ 945 de ori mai rapidă decât concat în crom și chiar mai rapid în Firefox. Această mare diferență provine din comportamentul CONCAT de a crea un nou tablou și de a copia datele în mod repetat, în timp ce Push crește tabloul existent mai mult și în loc, evitând realocările repetate ale memoriei.
Cu toate acestea, aceste caracteristici de performanță pot varia în funcție de scenariile de utilizare. Dacă obiectivul este o singură concatenare a două tablouri pre-alocate foarte mari, CONCAT ar putea performa relativ bine, deoarece alocă o dată și face copia o dată. În astfel de cazuri, abordarea de anexare unu-la-unu a lui Push ar putea provoca realocări multiple sau copiere internă, ceea ce ar putea reduce avantajul său teoretic. Cu toate acestea, pentru fuziunea repetată sau adăugarea multor elemente pe mai multe tablouri, Push tinde să fie amortizată o (1) pe adaos, deoarece tablourile alocă adesea memoria geometric (dublarea capacității atunci când este depășită), ceea ce o face extrem de eficientă în general.
Din perspectiva memoriei, mutația pe loc a lui Push înseamnă alocări mai puțin frecvente și potențial mai puține încordare asupra subsistemului de memorie. Metoda CONCAT, care necesită alocări noi și copiile datelor din nou, subliniază memoria și în cache mai mult, în special pentru tablouri mari. Această situație are ca rezultat operațiunile concate, care să depășească eventual limitele cache-ului CPU, ceea ce duce la timp mai lent de acces la memorie din cauza preluării datelor din cache-uri cu latență superioară sau a memoriei principale în mod repetat. Împingeți, evitând revizuirile către datele deja în tablou, poate folosi mai bine localitatea de cache.
Trebuie menționat că Push modifică tabloul original, în timp ce CONCAT păstrează imuabilitatea prin întoarcerea unui nou tablou. Această diferență este importantă în proiectarea aplicațiilor, dar are impact și asupra performanței. Concatenări imuabile cu CONCAT nu garantează efecte secundare, dar plătește prețul memoriei suplimentare și copierii, în timp ce Push tranzacționează imuabilitatea pentru viteză, modificând direct tabloul sursă.
Unele nuanțe includ faptul că motoarele JavaScript ar putea optimiza aceste operațiuni în mod diferit pe baza contextului și complexității. De exemplu, motoarele optimizează mai agresiv tipuri fixe sau mici. De asemenea, metoda CONCAT Signature acceptă în mod simultan apariția mai multor tablouri și valori (semnături supraîncărcate), care necesită aplatizarea internă și copierea etapelor care adaugă aerul aerian, în timp ce Push adaugă simplu elemente fără o astfel de aplatizare.
În ceea ce privește colectarea gunoiului, alocările frecvente implicate în CONCAT pot crește volumul de muncă pentru colectarea gunoiului, deoarece tablourile vechi devin aruncate după copiere. Acest lucru poate duce la pauze sau scăderi de performanță în scenarii de alocare ridicată. Push crește un tablou existent reduce frecvența alocărilor și, astfel, colectarea gunoiului deasupra capului.
În general, alegerea dintre împingere și concat implică o comprimare între viteză (apăsare) și imuabilitate/comoditate (CONCAT). Pentru operațiunile pe tablouri mari, cu performanță ca prioritate, Push este în general metoda preferabilă datorită manipulării mai eficiente a memoriei și a aerului mai mic. CONCAT -ul CONCAT de la crearea și copierea matricelor devine foarte costisitoare pe măsură ce dimensiunile tabloului cresc. În scenarii în care imuabilitatea este critică, CONCAT este utilizat în ciuda pedepsei de performanță.
În rezumat, Push prezintă de obicei o performanță mai bună și o memorie mai mică, în comparație cu CONCAT în contextul unor tablouri mari din cauza modificării la loc, a anexelor constante amortizate și a copierii reduse. CONCAT suferă de alocări suplimentare de memorie și costuri de copiere, deoarece creează un nou tablou de fiecare dată când se numește, ceea ce afectează atât timp, cât și utilizarea memoriei, în special cu tablouri foarte mari. Aceste diferențe sunt mărite atunci când contopește multe tablouri sau se ocupă de seturi de date masive, unde împingerea poate fi de sute până la mii de ori mai rapidă decât concatul în funcție de valori de referință. Cu toate acestea, în funcție de contextul de utilizare și de optimizările motorului, aceste modele generale pot avea excepții și ar trebui luate în considerare alături de necesitatea imuabilității și a întreținerii codului.