Pernyataan gelung JavaScript berprestasi tinggi dan kemahiran javascript pernyataan bersyarat

WBOY
Lepaskan: 2016-05-16 15:19:06
asal
1164 orang telah melayarinya

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);

Salin selepas log masuk

Dalam setiap gelung di atas, operasi ini akan berlaku setiap kali badan gelung dijalankan:

  • Perbandingan saiz berangka dalam keadaan kawalan (i < panjang)
  • Perbandingan yang mengawal sama ada keputusan keadaan adalah benar (i < panjang === benar)
  • Satu operasi kenaikan diri (i)
  • Satu carian tatasusunan (item[i])
  • Proses panggilan satu fungsi(item[i])

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--);

Salin selepas log masuk

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);

Salin selepas log masuk

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:

  • Lelaran terbalik sememangnya boleh meningkatkan sedikit prestasi kod, tetapi ia mengorbankan kebolehbacaan kod Melainkan pengoptimuman prestasi melampau diteruskan, tidak perlu menggunakan
  • .
  • Jika anda boleh melintasi tatasusunan menggunakan gelung biasa, jangan gunakan for-in dan for-each

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;
}
Salin selepas log masuk

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;
    }
  }
}
Salin selepas log masuk

这样优化后我们最多进行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;
}
Salin selepas log masuk

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];
Salin selepas log masuk

当数据量很大的时候,查找表的效率通常要比if-else语句和swtich-case语句高,查找表能用数字和字符串作为索引,而如果是字符串的情况下,最好用对象来代替数组。当然查找表的使用是有局限性的,每个case对应的结果只能是一个取值而不能是一系列的操作。

小结:

  • 当只有两个case或者case的value取值是一段连续的数字的时候,我们可以选择if-else语句
  • 当有3~10个case数并且case的value取值非线性的时候,我们可以选择switch-case语句
  • 当case数达到10个以上并且每次的结果只是一个取值而不是额外的JavaScript语句的时候,我们可以选择查找表

以上就是本文的全部内容,希望对大家的学习有所帮助。

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!