1. Penyataan gelung
Seperti yang kita sedia maklum, pernyataan gelung yang biasa digunakan termasuk untuk, sambil, buat sambil, untuk masuk dan untukSetiap. Kecuali prestasi for-in dan forEach sedikit lebih rendah, pilihan kami daripada tiga yang pertama biasanya lebih berdasarkan keperluan dan bukannya pertimbangan prestasi Hari ini kami akan menguji prestasi masing-masing dan memberitahu kami bahawa mereka masih boleh melakukan yang paling ekstrem kes. Apakah pengoptimuman yang boleh dilakukan.
Pertama, mari kita bincangkan sebab for-in dan forEach lebih perlahan daripada yang lain. for-in biasanya digunakan untuk melintasi nama atribut objek Memandangkan setiap operasi lelaran mencari atribut contoh itu sendiri dan atribut pada rantai prototaip pada masa yang sama, kecekapan pastinya rendah manakala forEach adalah lelaran berasaskan fungsi (perhatian khusus diperlukan) Walau bagaimanapun, semua versi IE tidak menyokongnya Jika perlu, anda boleh menggunakan perpustakaan seperti JQuery.
Kemudian mari kita lihat untuk apa, sambil dan buat sambil lakukan dalam setiap lelaran.
var length = items.length; for(var i = 0; i < length; i++) process(items[i]); var j = 0; while(j < length) process(items[j++]); var k = 0; do { process(items[k++]); } while(k < length);
Dalam setiap gelung di atas, operasi ini akan berlaku setiap kali badan gelung dijalankan:
Kami boleh meningkatkan prestasi gelung dengan membalikkan susunan tatasusunan:
for(var i = items.length; i--; ) process(items[i]); var j = items.length; while(j--) process(items[j]); var k = items.length - 1; do { process(items[k]); } while(k--);
Dalam contoh ini, gelung tertib terbalik digunakan dan operasi tolak disepadukan ke dalam keadaan gelung. Kini setiap keadaan kawalan hanya dibandingkan dengan 0. Keadaan kawalan dibandingkan dengan nilai benar Sebarang nombor bukan sifar ditukar kepada benar secara automatik, manakala nilai sifar bersamaan dengan palsu. Sebenarnya, keadaan kawalan dikurangkan daripada dua perbandingan (Adakah bilangan lelaran kurang daripada jumlah? Adakah ia benar?) kepada satu perbandingan (Adakah ia benar?). Ini dikurangkan daripada dua perbandingan kepada satu setiap lelaran, meningkatkan lagi kelajuan gelung.
Ujian prestasi:
Jadi adakah ini benar-benar berlaku? Wang sebenar tidak takut dengan pengesahan pelayar. Kod ujian adalah sangat mudah, merangkumi 8 fungsi untuk 8 situasi berbeza (maklumat profil tidak boleh dicetak dalam Firefox tanpa pemasa, sebabnya tidak diketahui):
// init array var a = []; var length = 10; for(var i = 0; i < length; i++) a[i] = 1; function for_in() { var sum = 0; for(var i in a) sum += a[i]; } function for_each() { var sum = 0; a.forEach(function(value, index, array) { sum += value; }); } function for_normal() { var sum = 0; for(var i = 0; i < length; i++) sum += a[i]; } function for_reverse() { var sum = 0; for(var i = length; i--; ) sum += a[i]; } function while_normal() { var sum = 0; var i = 0; while(i < length) sum += a[i++]; } function while_reverse() { var sum = 0; var i = length; while(i--) sum += a[i]; } function do_while_normal() { var sum = 0; var i = 0; do { sum += a[i++]; } while(i < length); } function do_while_reverse() { var sum = 0; var i = length - 1; do { sum += a[i]; } while(i--); } setTimeout(function() { console.profile(); for_in(); for_each(); for_normal(); for_reverse(); while_normal(); while_reverse(); do_while_normal(); do_while_reverse(); console.profileEnd(); }, 1000);
Apabila panjang tatasusunan ialah 100, kami mendapati bahawa hasil di bawah firefox sememangnya serupa dengan jangkaan: untuk-setiap dan untuk-dalam adalah tidak cekap, dan tertib terbalik adalah lebih cekap sedikit daripada tertib hadapan. (Profil di bawah chrome tidak dipaparkan kerana masa terlalu singkat)
Apabila volum data mencecah 1 juta, hasil di bawah firefox dan chrome adalah seperti yang dijangkakan, tetapi terdapat sedikit perbezaan. Prestasi for-in under ff adalah lebih baik daripada for-each, tetapi prestasi for-in under chrome adalah lemah dan amaran dikeluarkan secara langsung. Walaupun prestasi lelaran terbalik sedikit bertambah baik, peningkatan tidak banyak dan kebolehbacaan kod berkurangan.
Ringkasan:
2. Pernyataan bersyarat
Pernyataan bersyarat biasa termasuk if-else dan switch-case. Jadi bila hendak menggunakan if-else dan bila hendak menggunakan pernyataan switch-case?
Mari kita lihat kod pernyataan if-else yang mudah:
if (value == 0){ return result0; } else if (value == 1){ return result1; } else if (value == 2){ return result2; } else if (value == 3){ return result3; } else if (value == 4){ return result4; } else if (value == 5){ return result5; } else if (value == 6){ return result6; } else if (value == 7){ return result7; } else if (value == 8){ return result8; } else if (value == 9){ return result9; } else { return result10; }
Dalam kes yang paling teruk (nilai=10) kita mungkin perlu membuat 10 pertimbangan sebelum mengembalikan hasil yang betul. Jadi bagaimana kita mengoptimumkan kod ini? Strategi pengoptimuman yang jelas ialah menilai nilai yang paling berkemungkinan terlebih dahulu. Tetapi biasanya kita tidak tahu (pilihan yang paling mungkin Dalam kes ini, kita boleh menggunakan strategi carian pokok binari untuk pengoptimuman prestasi.
if (value < 6){ if (value < 3){ if (value == 0){ return result0; } else if (value == 1){ return result1; } else { return result2; } } else { if (value == 3){ return result3; } else if (value == 4){ return result4; } else { return result5; } } } else { if (value < 8){ if (value == 6){ return result6; } else { return result7; } } else { if (value == 8){ return result8; } else if (value == 9){ return result9; } else { return result10; } } }
这样优化后我们最多进行4次判断即可,大大提高了代码的性能。这样的优化思想有点类似二分查找,和二分查找相似的是,只有value值是连续的数字时才能进行这样的优化。但是代码这样写的话不利于维护,如果要增加一个条件,或者多个条件,就要重写很多代码,这时switch-case语句就有了用武之地。
将以上代码用switch-case语句重写:
switch(value){ case 0: return result0; case 1: return result1; case 2: return result2; case 3: return result3; case 4: return result4; case 5: return result5; case 6: return result6; case 7: return result7; case 8: return result8; case 9: return result9; default: return result10; }
swtich-case语句让代码显得可读性更强,而且swtich-case语句还有一个好处是如果多个value值返回同一个结果,就不用重写return那部分的代码。一般来说,当case数达到一定数量时,swtich-case语句的效率是比if-else高的,因为switch-case采用了branch table(分支表)索引来进行优化,当然各浏览器的优化程度也不一样。
除了if-else和swtich-case外,我们还可以采用查找表。
var results = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10]; //return the correct result return results[value];
当数据量很大的时候,查找表的效率通常要比if-else语句和swtich-case语句高,查找表能用数字和字符串作为索引,而如果是字符串的情况下,最好用对象来代替数组。当然查找表的使用是有局限性的,每个case对应的结果只能是一个取值而不能是一系列的操作。
小结:
以上就是本文的全部内容,希望对大家的学习有所帮助。