Javascript anahtarı vs. if… else if… else


143

Çocuklar birkaç sorum var:

  1. JavaScript'te bir switchifade ile bir arasında bir performans farkı var mı if...else?
  2. Öyleyse neden?
  3. Tarayıcıların davranışı switchve if...elsetarayıcılar arasında farklı mı? (FireFox, IE, Chrome, Opera, Safari)

Bu soruyu sormanın nedeni switch, Firefox'ta yaklaşık 1000'li vakalarla yapılan bir açıklamada daha iyi performans elde etmem gibi görünüyor .


Düzenlenen Unfortuantly bu Javascript derlenmiş kütüphaneden serverside üretiliyor benim kod değil ve koda erişim sağlayamamaktadır. Javascript üreten yöntem denir

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

note arrayofvalues, virgülle ayrılmış bir listedir.

ürettiği şey

function [name] (value) {
  if (value == [value from array index x]) {
     [action from array index x]
  }
}

Not: where [name]= sunucu tarafı işlevine geçen ad

Şimdi bir TextArea içine eklenecek fonksiyonun çıktısını değiştirdim, fonksiyon boyunca ayrıştırmak için bazı JavaScript kodu yazdım ve bir dizi caseifadeye dönüştürdüm .

Sonunda işlevi çalıştırın ve iyi çalışır ama performans IE ve Firefox farklıdır.


1
Neyin en uygun olduğunu incelemek için bir kod örneği öneririm. Demek istediğim, bunu sorman için bir sebep olmalı, değil mi?
jcolebrand

Lütfen ne yaptığınızı gönderin, çünkü uzun deneyimlerim için 100 durumlu bir anahtar ifadesi veya / part serisi iyi bir fikir ise 100 bölümlük bir anahtar deyimi diyeceğim çok az durum var.
Sivri

üzgünüm 100'ler değil binlerce koşul
John Hartsock

2
Herkes, girdi için teşekkürler. Ama benim sorunum aslında if ve swith ifadeleri arasındaki fark değildi. İfadenin içinde çalışan kod buydu. Yardımınız için hepinize + 1'leyin. Bu durum için özür dileriz. Bazen çözümü bulmak için başka biriyle konuşmanız gerekir.
John Hartsock

Yanıtlar:


113

Genellemelerde cevaplama:

  1. Evet, genellikle.
  2. Daha Fazla Bilgi Burada
  3. Evet, her biri farklı bir JS işleme motoruna sahip olduğundan, aşağıdaki sitede bir test çalıştırırken, anahtar her zaman if, elseif'i çok sayıda yinelemede gerçekleştirdi.

Test sitesi


1
Buradaki hangi koşulların ne zaman kullanılacağının TLDR'sini istiyorsanız, makalede aşağıdakilere hitap eden bir segmente doğrudan bağlantı: oreilly.com/server-administration/excerpts/even-faster-websites/…
edhedges

2
@Tommy İyi makale, paylaştığınız için teşekkürler. Ancak makale JS switchile if/thenifadeler arasında ihmal edilebilir bir performans farkı olduğunu belirtmektedir . Makale bunun sivilceli switchoptimizasyondan ve farklı JS motorlarının çalışmasının farklı yollarından kaynaklandığını belirtir . Alıntı:Since most JavaScript engines don’t have such optimizations, performance of the switch statement is mixed.
Jasper

3
Bu açıklamada ölçülebilir bir şey gösteriliyor mu? Birçok "en iyi uygulamalar / erken optimizasyon" varsayımı gibi okur. Ayrıca 7 yıl önce yazılmış, bu nedenle javascript optimizasyonları muazzam bir şekilde değişti. Derlenmiş dillerde, bu üç işlem arasındaki performans farkı "neredeyse hiç bakım için yeterince önemli değildir". Gerçek performansı etkilemeyecek şeyleri optimize etmeye zahmet etmeyin. Okunabilirliği optimize edin.
Thomson Comer

3
@Tommy « Daha Fazla Bilgi Buraya Bakın » 404 verir, orada ne vardı?
LogicDaemon

2
@LogicDaemon - IIRC, bazı JS performans değerlendirmeleri / tartışmalarına giren bazı oRielly metin kutusuna bir bağlantıydı
Tommy

61

Bazen hiçbirini kullanmamak daha iyidir. Örneğin, "gönderme" durumunda, Javascript işleri tamamen farklı bir şekilde yapmanızı sağlar:

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

Bir nesne oluşturarak çok yönlü dallamanın ayarlanmasının birçok avantajı vardır. İşlevselliği dinamik olarak ekleyebilir ve kaldırabilirsiniz. Veriden dağıtım tablosunu oluşturabilirsiniz. Programlı olarak inceleyebilirsiniz. İşleyicileri diğer işlevlerle oluşturabilirsiniz.

Bir "vaka" eşdeğerine ulaşmak için bir işlev çağrısının ek yükü vardır, ancak belirli bir anahtarın işlevini bulmak için karma aramanın avantajı (çok sayıda vaka olduğunda) vardır.


2
Stratejiniz iyi ve sık sık kullanıyorum. Ancak @Michael Geary stackoverflow.com/a/45336805/5936119 tarafından işaret edildiği gibi , harita değişkeni gönderim bağlamının dışında bildirilmelidir, aksi takdirde her zaman yeniden değerlendirilir.
Daniel Santana

@DanielSantana doğru ama bunun çok pahalı olduğundan şüpheliyim. Özellikle, bir işlev başlangıçta ayrıştırıldıktan sonra , metnin statik olması nedeniyle kodun kendisinin yeniden oluşturulması gerekmez.
Sivri

18

A switchve arasındaki performans farkı if...else if...elseküçüktür, temelde aynı işi yaparlar. Aralarında fark yaratabilecek bir fark, test edilecek ifadenin switcharada bir değerlendirilmesidir ve her biri için değerlendirilir if. İfadeyi değerlendirmek pahalıysa, bir kez yapmak elbette yüz kez yapmaktan daha hızlıdır.

Bu komutların (ve genel olarak tüm komut dosyalarının) uygulanmasındaki fark, tarayıcılar arasında biraz farklıdır. Farklı tarayıcılarda aynı kod için oldukça büyük performans farklılıkları görmek yaygındır.

Tüm tarayıcılardaki tüm kodları neredeyse hiç test edemediğiniz için, yaptığınız işe en uygun kodu seçmeli ve nasıl yapıldığını optimize etmek yerine yapılan iş miktarını azaltmaya çalışmalısınız.


7
  1. Bir fark varsa, farkedilecek kadar büyük olmayacaktır.
  2. N / A
  3. Hayır, hepsi aynı şekilde çalışıyor.

Temel olarak, kodu en okunabilir yapan her şeyi kullanın. Kesinlikle bir veya diğer yapıların daha temiz, daha okunabilir ve daha sürdürülebilir olmasını sağlayan yerler vardır. Bu, JavaScript kodunda birkaç nanosaniyeden tasarruf etmenin çok daha önemlidir.


5
Özellikle javascriptte, anlambilim ve okunabilirlik (ve dolayısıyla sürdürülebilirlik) , benzersiz bir tarayıcı sürümü bilgisayar donanımı ve işletim sistemi kombinasyonu arasındaki if..elseve bunlardan switchkaynaklanan herhangi bir yerel performans farkını gölgede bırakır .
jball

2
Kabul edersem bilmiyorum, gerçekten büyük bir veritabanı, bir ağaç vb.
İle

2
kesinlikle katılmıyorum. web uygulamaları gittikçe karmaşıklaştıkça, bu fark uygulama için önemli olabilir ve tarayıcılara bağlı olarak değişebilir.
joshvermaire

7
Önemli olan temiz, bakımı kolay kod yazmaktır. Bir performans sorunu görüldüğünde - profil. Ardından hangi kodu düzelteceğinizi belirleyin. Varsayılan performans sorunları için sürdürülebilirliği feda etmeyin.
Jon Benedicto

3
'aksi takdirde ...' O (n), 'anahtar' ise O (1) veya O (log (n)) olur. Dürüstlükle, farkın asla yeterince büyük olamayacağını nasıl söyleyebilirsiniz? Bir milyon vakaya geçin (kod üretilirse kolayca mümkündür) ve kesinlikle en azını söylemek gerekir.
dragonroot

6

Sözdizimi dışında bir anahtar, bunu yapan bir ağaç kullanılarak uygulanabilirken O(log n), bir if / elseO(n) işlemsel yaklaşımla uygulanmalıdır . Daha sık olarak, her ikisi de prosedürel olarak işlenir ve tek fark sözdizimidir ve dahası, statik olarak 10k vakaları if / else yazmıyorsanız, gerçekten önemli mi?


7 yıl sonra ... Sabit sayısal durum değerleri dışında ağaç uygulamasının nasıl mümkün olduğunu göremiyorum).
Ed Staub

4

Pointy'nin cevabı , / switchveya nesnesine alternatif olarak bir nesnenin kullanılmasını önerir . Ben de bu yaklaşımı seviyorum, ancak her işlev çağrıldığında yanıt kodu yeni bir nesne oluşturur :ifelsemapdispatch

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

Eğer mapgirişlerin çok sayıda içerir, bu önemli ek yük oluşturabilir. Eylem haritasını yalnızca bir kez ayarlamak ve ardından her defasında önceden oluşturulmuş haritayı kullanmak daha iyidir, örneğin:

var actions = {
    'explode': function() {
        prepExplosive();
        if( flammable() ) issueWarning();
        doExplode();
    },

    'hibernate': function() {
        if( status() == 'sleeping' ) return;
        // ... I can't keep making this stuff up
    },
    // ...
};

function dispatch( name ) {
    var action = actions[name];
    if( action ) action();
}

3

Javascript'te bir switch deyimi ile bir if ... else if .... else arasında bir performans farkı var mı?

Bence switchbirden fazla if-elsekoşulu önlemek istiyorsanız faydalı / kısa .

Anahtarın davranışı ve if ... else if ... else tarayıcılar arasında farklı mı? (FireFox, IE, Chrome, Opera, Safari)

Davranış tüm tarayıcılarda aynıdır :)


5
switch is useful/short if you want prevent multiple if-else conditions.Evet efendim, harika gönderi.
NiCk Newman

1
  1. Çalışma tezgahı bazı durumlarda çok küçük farklılıklara neden olabilir, ancak işleme biçimi yine de tarayıcıya bağımlıdır, bu yüzden rahatsız etmeye değmez
  2. Farklı işleme yöntemleri nedeniyle
  3. Davranış yine de farklı olursa tarayıcıya diyemezsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.