SORU
12 Temmuz 2011, Salı


Daha büyük-daha/için anahtar deyim daha

böyle bir switch deyimi kullanmak istiyorum:

switch (scrollLeft) {
  case (<1000):
   //do stuff
   break;
  case (>1000 && <2000):
   //do stuff
   break;
}

Şimdi bu ifadeleri (<1000) veya (>1000 && <2000) ya da (farklı nedenlerden dolayı, tabii ki) çalışmaz biliyorum. Sorduğum şey sadece bunu yapmak için en etkili yoldur. 30 if ifadeleri kullanmaktan nefret ederim, daha doğrusu geçiş sözdizimi kullanmak istiyorum. Yapabileceğim bir şey var mı?

CEVAP
4 EYLÜL 2012, Salı


Diğer cevapları çözümleri baktığımda kötü performans için biliyorum bazı şeylerin gördüm. Bir yorum bunu koyacaktım ama kıyaslama için daha iyi olduğunu ve sonuçlarını paylaşmak düşündüm. 29**. Aşağıda benim sonuçları (ymmv) her tarayıcıda hızlı ameliyat sonrası normalize (ms mutlak zaman almak için normalleştirilmiş değeri ile 1.0 saat çarpın).

                    Chrome  Firefox Opera   MSIE    Safari  Node
-------------------------------------------------------------------
1.0 time               37ms    73ms    68ms   184ms    73ms    21ms
if-immediate            1.0     1.0     1.0     2.6     1.0     1.0
if-indirect             1.2     1.8     3.3     3.8     2.6     1.0
switch-immediate        2.0     1.1     2.0     1.0     2.8     1.3
switch-range           38.1    10.6     2.6     7.3    20.9    10.4
switch-range2          31.9     8.3     2.0     4.5     9.5     6.9
switch-indirect-array  35.2     9.6     4.2     5.5    10.7     8.6
array-linear-switch     3.6     4.1     4.5    10.0     4.7     2.7
array-binary-switch     7.8     6.7     9.5    16.0    15.0     4.9

Windows üzerinde yapılan Test aşağıdaki sürümleri ile 7 32 bit:Krom 21.0.1180.89 m,Firefox 15.0,Opera 12.02,MSIE 9.0.8112,Safari 5.1.7.DüğümWindows XP node.js üzerinde zamanlayıcı çözünürlük 10ms yerine 1ms çünkü 64 bit bir Linux kutusu üzerinde çalışacak.

Eğer acil

Bu, test edilen tüm ortamlarda en hızlı, dışındadavullarMSIE! (sürpriz, sürpriz). Bu uygulamak için önerilen yöntemdir.

if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else

-dolaylı

Bu switch-indirect-array bir türevi olduğunu ama if-bildirimleri yerine ve çok daha hızlı switch-indirect-array daha neredeyse tüm test ortamlarda gerçekleştirir.

values=[
   1000,  2000, ... 30000
];
if (val < values[0]) { /* do something */ } else
if (val < values[1]) { /* do something */ } else
...
if (val < values[29]) { /* do something */ } else

geçin hemen

Bunu çok hızlı bir şekilde test ortamları ve MSIE en hızlı aslında. Bir hesaplama bir dizin almak için ne zaman işe yarıyor.

switch (Math.floor(val/1000)) {
  case 0: /* do something */ break;
  case 1: /* do something */ break;
  ...
  case 29: /* do something */ break;
}

geçiş aralığı

Bu, test edilen tüm ortamlarda en hızlı dışında yaklaşık 6 ila 40 kat daha yavaş. yaklaşık bir buçuk kat daha uzun sürer nerede Opera için. Motoru çünkü çok yavaş değer iki kez her durum için karşılaştırmak için. MSIE sadece 6 kat daha uzun sürer Chrome neredeyse 40 kat daha uzun Chrome en hızlı işlem göre bu tamamlamak için gereken, şaşırtıcı bir şekilde. Ama gerçek zaman farkı sadece iyilik yap diye 74ms 1337ms en MSIE oldu(!).

switch (true) {
  case (0 <= val &&  val < 1000): /* do something */ break;
  case (1000 <= val &&  val < 2000): /* do something */ break;
  ...
  case (29000 <= val &&  val < 30000): /* do something */ break;
}

anahtar hücresi range2

Bu sadece tek bir vaka başına karşılaştırın ve Opera dışında, bu nedenle daha hızlı, ama hala çok yavaş switch-range ama bir çeşididir. Case deyimi sipariş motorun kaynak kodu sipariş ECMAScript262:5 12.11 her durumda test edecek çok önemlidir

switch (true) {
  case (val < 1000): /* do something */ break;
  case (val < 2000): /* do something */ break;
  ...
  case (val < 30000): /* do something */ break;
}

-dolaylı-dizi geçin

Bu değişken aralıkları, bir dizi içinde depolanır. Bu Krom tüm test ortamlarında yavaş ve çok yavaş.

values=[1000,  2000 ... 29000, 30000];

switch(true) {
  case (val < values[0]): /* do something */ break;
  case (val < values[1]): /* do something */ break;
  ...
  case (val < values[29]): /* do something */ break;
}

dizi doğrusal arama

Bu bir dizi, ve geçiş değerleri doğrusal bir arama birleşimidir sabit değerler ile ifade. Neden bir zaman bu kullanmak isteyebilirsiniz değerleri çalışma zamanı kadar ünlü değildir. Her test ortamında yavaş ve MSIE neredeyse 10 kat daha uzun sürer.

values=[1000,  2000 ... 29000, 30000];

for (sidx=0, slen=values.length; sidx < slen;   sidx) {
  if (val < values[sidx]) break;
}

switch (sidx) {
  case 0: /* do something */ break;
  case 1: /* do something */ break;
  ...
  case 29: /* do something */ break;
}

dizi-ikili-geçiş

Bu ikili arama array-linear-switch ama bir çeşididir. Ne yazık ki doğrusal aramaya göre daha yavaş olur. Eğer benim uygulama ise veya doğrusal arama, daha iyi bilmiyorum. Ayrıca keyspace küçük olduğunu olabilir.

values=[0, 1000,  2000 ... 29000, 30000];

while(range) {
  range = Math.floor( (smax - smin) / 2 );
  sidx = smin   range;
  if ( val < values[sidx] ) { smax = sidx; } else { smin = sidx; }
}

switch (sidx) {
  case 0: /* do something */ break;
  ...
  case 29: /* do something */ break;
}

Sonuç

Eğer performans önemli ise, derhal değerleri ile if-tablolar veya switch kullanın.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Barnacules Nerdgasm

    Barnacules N

    20 Temmuz 2006
  • Epic Tutorials for iPhone, iPad and iOS

    Epic Tutoria

    18 EYLÜL 2011
  • foreignimage

    foreignimage

    13 HAZİRAN 2006