Saya menjalankan kode ini dan mendapatkan hasil di bawah ini. Saya penasaran ingin tahu mengapa []
lebih cepat?
console.time('using[]')
for(var i=0; i<200000; i++){var arr = []};
console.timeEnd('using[]')
console.time('using new')
for(var i=0; i<200000; i++){var arr = new Array};
console.timeEnd('using new')
- menggunakan
[]
: 299ms - menggunakan
new
: 363ms
Terima kasih kepada Raynos di sini adalah patokan kode ini dan beberapa cara yang lebih mungkin untuk mendefinisikan variabel.
javascript
performance
Mohsen
sumber
sumber
[]
adalah samanew Array()
dalam hal kode sumber, bukan objek yang dikembalikan dari ekspresiJawaban:
Lebih lanjut memperluas jawaban sebelumnya ...
Dari perspektif kompiler umum dan mengabaikan optimasi spesifik VM:
Pertama, kita melalui fase analisis leksikal di mana kita tokenize kode.
Sebagai contoh, token berikut dapat diproduksi:
Mudah-mudahan ini akan memberi Anda visualisasi yang cukup sehingga Anda dapat memahami berapa banyak (atau kurang) pemrosesan yang diperlukan.
Berdasarkan token di atas, kita tahu sebagai fakta ARRAY_INIT akan selalu menghasilkan array. Karena itu kami cukup membuat sebuah array dan mengisinya. Sejauh ambiguitas, tahap analisis leksikal telah membedakan ARRAY_INIT dari accessor properti objek (misalnya
obj[foo]
) atau tanda kurung di dalam string / regex literal (mis. "Foo [] bar" atau / [] /)Ini sangat kecil, tetapi kami juga memiliki lebih banyak token
new Array
. Selain itu, belum sepenuhnya jelas bahwa kami hanya ingin membuat array. Kita melihat token "baru", tetapi "baru" apa? Kami kemudian melihat token IDENTIFIER yang menandakan kami menginginkan "Array" baru, tetapi JavaScript VM pada umumnya tidak membedakan token dan token IDENTIFIER untuk "objek global asli." Karena itu...Kami harus mencari rantai cakupan setiap kali kami menemukan token IDENTIFIER. Javascript VMs berisi "objek Aktivasi" untuk setiap konteks eksekusi yang mungkin berisi objek "argumen", variabel yang ditentukan secara lokal, dll. Jika kita tidak dapat menemukannya di objek Aktivasi, kita mulai mencari rantai lingkup sampai kita mencapai lingkup global . Jika tidak ada yang ditemukan, kami melempar
ReferenceError
.Setelah kami menemukan deklarasi variabel, kami memanggil konstruktor.
new Array
adalah pemanggilan fungsi implisit, dan aturan praktisnya adalah pemanggilan fungsi lebih lambat selama eksekusi (karenanya mengapa kompiler C / C ++ statis memungkinkan "fungsi inlining" - yang harus dilakukan mesin JS JIT seperti SpiderMonkey saat on-the-fly)The
Array
konstruktor kelebihan beban. Konstruktor Array diimplementasikan sebagai kode asli sehingga memberikan beberapa peningkatan kinerja, tetapi masih perlu memeriksa panjang argumen dan bertindak sesuai. Selain itu, jika hanya ada satu argumen yang disediakan, kita perlu memeriksa lebih lanjut jenis argumen. Array baru ("foo") menghasilkan ["foo"] sedangkan Array baru (1) menghasilkan [tidak terdefinisi]Jadi untuk menyederhanakan semuanya: dengan literal array, VM tahu kita menginginkan sebuah array; dengan
new Array
, VM perlu menggunakan siklus CPU tambahan untuk mencari tahu apa yangnew Array
sebenarnya dilakukan.sumber
Salah satu alasan yang mungkin adalah bahwa
new Array
memerlukan pencarian nama padaArray
(Anda dapat memiliki variabel dengan nama itu dalam lingkup), sedangkan[]
tidak.sumber
Array
kecuali satu argumenlen
dan beberapa argumen. Dimana[]
hanya menerima banyak argumen. Juga tes firefox menunjukkan hampir tidak ada perbedaan.var Array = window.Array
meningkatkan kinerjanew Array
tes.Pertanyaan bagus. Contoh pertama disebut array literal. Ini adalah cara yang disukai untuk membuat array di antara banyak pengembang. Bisa jadi perbedaan kinerja disebabkan oleh memeriksa argumen dari panggilan Array () baru dan kemudian membuat objek, sedangkan literal membuat array secara langsung.
Perbedaan yang relatif kecil dalam kinerja mendukung hal ini, saya pikir. Anda bisa melakukan tes yang sama dengan Object dan objek literal {} dengan cara.
sumber
Ini masuk akal
http://www.dyn-web.com/tutorials/obj_lit.php
sumber
Juga menarik, jika panjang array diketahui sebelumnya (elemen akan ditambahkan tepat setelah pembuatan), penggunaan konstruktor array dengan panjang tertentu jauh lebih cepat di Google Chrome 70+ baru-baru ini.
" Array baru ( % ARR_LENGTH% ) " - 100% (lebih cepat) !
" [] " - 160-170% (lebih lambat)
Tes dapat ditemukan di sini - https://jsperf.com/small-arr-init-with-known-length-brackets-vs-new-array/2
Catatan: hasil ini diuji di Google Chrome v.70 + ; di Firefox v.70 dan IE kedua varian hampir sama.
sumber