Javascript สลับกับถ้า ... เป็นอย่างอื่นถ้าเป็นอย่างอื่น


143

พวกฉันมีคำถามสองสามข้อ:

  1. มีความแตกต่างของประสิทธิภาพใน JavaScript ระหว่างswitchข้อความสั่งและข้อความif...elseหรือไม่?
  2. ถ้าเป็นเช่นนั้นทำไม
  3. พฤติกรรมของswitchและif...elseแตกต่างกันในเบราว์เซอร์หรือไม่ (FireFox, IE, Chrome, Opera, Safari)

เหตุผลในการถามคำถามนี้ดูเหมือนว่าฉันจะได้รับประสิทธิภาพที่ดีขึ้นในswitchข้อความที่มีประมาณ 1,000 กรณีใน Firefox


แก้ไขแล้ว Unfortuantly นี่ไม่ใช่รหัสของฉัน Javascript กำลังสร้างเซิร์ฟเวอร์จากไลบรารีที่รวบรวมและฉันไม่สามารถเข้าถึงรหัสได้ วิธีการที่ผลิตจาวาสคริปต์นั้นเรียกว่า

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

note arrayofvaluesเป็นรายการที่คั่นด้วยเครื่องหมายจุลภาค

สิ่งที่มันผลิตคือ

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

หมายเหตุ: โดยที่[name]= ชื่อที่ส่งผ่านไปยังฟังก์ชันเซิร์ฟเวอร์

ตอนนี้ฉันเปลี่ยนเอาท์พุทของฟังก์ชั่นที่จะแทรกเข้าไปใน TextArea เขียนโค้ดจาวาสคริปต์บางส่วนเพื่อแยกวิเคราะห์ฟังก์ชั่นและแปลงเป็นชุดของcaseข้อความสั่ง

ในที่สุดฉันก็เรียกใช้ฟังก์ชั่นและมันก็ทำงานได้ดี แต่ประสิทธิภาพแตกต่างกันใน IE และ Firefox


1
ฉันขอแนะนำตัวอย่างโค้ดเพื่อตรวจสอบสิ่งที่ดีที่สุด ฉันหมายความว่ามีเหตุผลที่คุณถามสิ่งนี้ใช่ไหม
jcolebrand

กรุณาโพสต์สิ่งที่คุณทำเพราะมีประสบการณ์น้อยมากที่ฉันจะบอกว่าคำสั่งสลับ 100 กรณีหรือ 100 ส่วนถ้า / ชุดอื่นเป็นความคิดที่ดี
แหลม

ขออภัยที่ไม่ใช่ 100s แต่เงื่อนไขหลายพัน
John Hartsock

2
ทุกคนขอบคุณสำหรับการป้อนข้อมูล แต่ปัญหาของฉันไม่ใช่ความแตกต่างระหว่าง if and swith statments มันเป็นรหัสที่ทำงานภายในคำสั่ง +1 ให้กับทุกคนสำหรับความช่วยเหลือของคุณ ขออภัยในความไม่สะดวก บางครั้งคุณเพียงแค่ต้องคุยกับบุคคลอื่นเพื่อหาทางแก้ไข
John Hartsock

คำตอบ:


113

คำตอบทั่วไป:

  1. ใช่แล้ว
  2. ดูข้อมูลเพิ่มเติมได้ที่นี่
  3. ใช่เพราะแต่ละอันมีเอ็นจิ้นการประมวลผล JS ที่แตกต่างกันอย่างไรก็ตามในการรันการทดสอบบนไซต์ด้านล่างสวิตช์จะทำงานหาก if ifif หากมีการวนซ้ำจำนวนมาก

เว็บไซต์ทดสอบ


1
หากคุณต้องการ TLDR เวลาที่จะใช้เงื่อนไขใด ๆ ที่นี่เป็นการเชื่อมโยงโดยตรงไปยังกลุ่มในบทความที่ระบุว่า: oreilly.com/server-administr/excerpts/even-faster-websites/ …
edhedges

2
@Tommy บทความที่ดีขอบคุณสำหรับการแบ่งปัน อย่างไรก็ตามบทความระบุว่ามีความแตกต่างเล็กน้อยระหว่างประสิทธิภาพswitchและif/thenคำสั่งใน JS บทความระบุว่าสิ่งนี้เกิดจากการปรับให้switchเหมาะสมที่สุดและวิธีการทำงานของเอ็นจิน JS ที่แตกต่างกัน อ้างอิง:Since most JavaScript engines don’t have such optimizations, performance of the switch statement is mixed.
Jasper

3
มีสิ่งใดในเชิงปริมาณที่แสดงในคำอธิบายนี้หรือไม่? มันอ่านการคาดคะเน "การปฏิบัติที่ดีที่สุด / การเพิ่มประสิทธิภาพก่อนวัยอันควร" จำนวนมาก มันเขียนขึ้นเมื่อ 7 ปีที่แล้วดังนั้นการเพิ่มประสิทธิภาพจาวาสคริปต์จึงเปลี่ยนไปอย่างมากในเวลานี้ ในภาษาที่คอมไพล์ความแตกต่างของประสิทธิภาพระหว่างการดำเนินการทั้งสามนี้คือ อย่ารบกวนการปรับแต่งสิ่งต่าง ๆ ที่จะไม่ส่งผลต่อประสิทธิภาพที่แท้จริง เพิ่มประสิทธิภาพการอ่าน
Thomson Comer

3
@Tommy « ดูข้อมูลเพิ่มเติมที่นี่ »ให้ 404 มีอะไรบ้าง
LogicDaemon

2
@LogicDaemon - IIRC เป็นลิงก์ไปยังกล่องข้อความ oRielly ที่เข้าสู่การพิจารณาประสิทธิภาพ JS / การอภิปรายในเชิงลึกบางอย่าง
Tommy

61

บางครั้งมันก็ยังดีกว่าที่จะใช้ ตัวอย่างเช่นในสถานการณ์ "ส่ง" Javascript ให้คุณทำสิ่งต่าง ๆ โดยสิ้นเชิง:

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

การตั้งค่าการแยกหลายทางด้วยการสร้างวัตถุมีข้อดีหลายประการ คุณสามารถเพิ่มและลบฟังก์ชั่นแบบไดนามิก คุณสามารถสร้างตารางการจัดส่งจากข้อมูล คุณสามารถตรวจสอบได้โดยทางโปรแกรม คุณสามารถสร้างตัวจัดการด้วยฟังก์ชันอื่น ๆ

มีโอเวอร์เฮดเพิ่มเติมของการเรียกใช้ฟังก์ชันเพื่อให้ได้เท่ากับ "case" แต่ข้อดี (เมื่อมีหลายกรณี) ของการค้นหา hash เพื่อค้นหาฟังก์ชันสำหรับคีย์เฉพาะ


2
กลยุทธ์ของคุณดีและฉันใช้บ่อยๆ แต่ตามที่ชี้โดย @Michael Geary stackoverflow.com/a/45336805/5936119ตัวแปรแผนที่จะต้องประกาศนอกบริบทการจัดส่งมิฉะนั้นจะมีการประเมินใหม่เสมอ
Daniel Santana

@DanielSantana จริง แต่ฉันสงสัยว่ามีราคาแพงมาก โดยเฉพาะอย่างยิ่งเมื่อฟังก์ชั่นเริ่มต้นในการแยกวิเคราะห์รหัสตัวเองไม่จำเป็นต้องสร้างใหม่เป็นข้อความที่คงที่
Pointy

18

ความแตกต่างของประสิทธิภาพระหว่าง a switchและif...else if...elseมีขนาดเล็กโดยทั่วไปพวกเขาทำงานเดียวกัน หนึ่งความแตกต่างระหว่างพวกเขาที่อาจสร้างความแตกต่างก็คือการแสดงออกในการทดสอบการประเมินเพียงครั้งเดียวในขณะที่การประเมินผลสำหรับแต่ละswitch ifถ้ามันมีค่าใช้จ่ายสูงในการประเมินการแสดงออกการทำครั้งเดียวแน่นอนเร็วกว่าการทำร้อยครั้ง

ความแตกต่างในการใช้งานคำสั่งเหล่านั้น (และสคริปต์ทั้งหมด) แตกต่างกันเล็กน้อยระหว่างเบราว์เซอร์ เป็นเรื่องปกติที่จะเห็นความแตกต่างของประสิทธิภาพค่อนข้างมากสำหรับรหัสเดียวกันในเบราว์เซอร์ที่ต่างกัน

ในขณะที่คุณสามารถทดสอบประสิทธิภาพรหัสทั้งหมดในเบราว์เซอร์ทั้งหมดได้ยากคุณควรไปหารหัสที่เหมาะสมที่สุดสำหรับสิ่งที่คุณกำลังทำและพยายามลดปริมาณงานที่ทำแทนที่จะปรับวิธีการทำงานให้ดีที่สุด


7
  1. หากมีความแตกต่างมันจะไม่ใหญ่พอที่จะสังเกตเห็น
  2. N / A
  3. ไม่พวกมันทำงานเหมือนกันหมด

โดยทั่วไปให้ใช้สิ่งที่ทำให้โค้ดอ่านได้มากที่สุด มีสถานที่แน่นอนที่หนึ่งหรือสิ่งก่อสร้างอื่น ๆ ทำให้สะอาดขึ้นอ่านได้ง่ายขึ้นและบำรุงรักษาได้มากขึ้น สิ่งนี้สำคัญยิ่งกว่าที่อาจช่วยประหยัดเวลาสักสองสามวินาทีในโค้ด JavaScript


5
โดยเฉพาะอย่างยิ่งในจาวาสคริปต์ความหมายและความสามารถในการอ่านได้ (และดังนั้นความสามารถในการบำรุงรักษา) จึงแตกต่างกันระหว่างความแตกต่างของประสิทธิภาพที่แปลเป็นภาษาท้องถิ่นif..elseและswitchเกิดจากฮาร์ดแวร์คอมพิวเตอร์รุ่นเบราว์เซอร์ที่ไม่เหมือนใคร
jball

2
ฉันไม่รู้ว่าฉันเห็นด้วยหรือไม่อาจสังเกตได้ว่ามันถูกใช้ในวงวนด้วยฐานข้อมูลขนาดใหญ่การสำรวจต้นไม้เป็นต้น
ghoppe

2
ฉันไม่เห็นด้วยอย่างแน่นอน เมื่อเว็บแอปพลิเคชันมีความซับซ้อนมากขึ้นความแตกต่างนี้อาจมีความสำคัญสำหรับแอปพลิเคชันและสามารถเปลี่ยนแปลงได้ขึ้นอยู่กับเบราว์เซอร์
joshvermaire

7
สิ่งสำคัญคือการเขียนรหัสที่สะอาดและบำรุงรักษาได้ เมื่อพบปัญหาเรื่องประสิทธิภาพ - โปรไฟล์ จากนั้นพิจารณาว่าจะแก้ไขรหัสใด อย่าเสียสละความสามารถในการบำรุงรักษาสำหรับปัญหาด้านประสิทธิภาพที่สมมติขึ้น
Jon Benedicto

3
'if else ถ้า else ... ' คือ O (n) ในขณะที่ 'switch' เป็น O (1) หรือ O (log (n)) คุณจะบอกความแตกต่างได้โดยสุจริตว่าจะไม่มีวันมากพอได้อย่างไร มีหลายล้านกรณีที่สลับกัน (เป็นไปได้อย่างง่ายดายหากมีการสร้างรหัส) และคุณจะสังเกตได้ว่าพูดน้อยที่สุด
dragonroot

6

นอกเหนือจากวากยสัมพันธ์สวิตช์สามารถนำมาใช้โดยใช้ต้นไม้ซึ่งทำให้มันO(log n)ในขณะที่ถ้า / อื่นจะต้องมีการดำเนินการด้วยO(n)วิธีการขั้นตอน บ่อยครั้งที่พวกเขาถูกประมวลผลทั้งขั้นตอนและความแตกต่างเพียงอย่างเดียวคือไวยากรณ์และยิ่งไปกว่านั้นมันมีความสำคัญ - เว้นแต่คุณจะพิมพ์กรณี 10k แบบคงที่ถ้า / อื่นอยู่แล้ว?


7 ปีต่อมา ... ฉันไม่เห็นว่าการใช้งานต้นไม้นั้นเป็นไปได้อย่างไรยกเว้นในกรณีที่มีค่าตัวเลขคงที่)
Ed Staub

4

คำตอบแหลมของแสดงให้เห็นการใช้ตัวอักษรวัตถุเป็นทางเลือกให้นั้นswitchหรือ/if elseฉันชอบวิธีนี้เช่นกัน แต่รหัสในคำตอบจะสร้างmapวัตถุใหม่ทุกครั้งที่dispatchมีการเรียกใช้ฟังก์ชัน:

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

หากmapมีรายการจำนวนมากสิ่งนี้สามารถสร้างค่าใช้จ่ายที่สำคัญ เป็นการดีกว่าที่จะตั้งค่าแผนที่การกระทำเพียงครั้งเดียวแล้วใช้แผนที่ที่สร้างขึ้นแล้วในแต่ละครั้งตัวอย่างเช่น:

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

มีความแตกต่าง preformance ใน Javascript ระหว่างคำสั่งเปลี่ยนและถ้า ... อื่นถ้า .... อื่น?

ฉันไม่คิดอย่างswitchนั้นมีประโยชน์ / สั้นถ้าคุณต้องการป้องกันหลายif-elseเงื่อนไข

พฤติกรรมของสวิตช์และถ้า ... เป็นอย่างอื่นถ้า ... แตกต่างกันในเบราว์เซอร์หรือไม่ (FireFox, IE, Chrome, Opera, Safari)

พฤติกรรมเหมือนกันในทุกเบราว์เซอร์ :)


5
switch is useful/short if you want prevent multiple if-else conditions.ครับท่านโพสต์ยอดเยี่ยม
NiCk Newman

1
  1. การปรับแต่งอาจทำให้เกิดความแตกต่างเล็กน้อยในบางกรณี แต่วิธีการประมวลผลขึ้นอยู่กับเบราว์เซอร์อยู่แล้วดังนั้นจึงไม่คุ้มค่าที่จะไปรบกวน
  2. เนื่องจากวิธีการประมวลผลที่แตกต่างกัน
  3. คุณไม่สามารถเรียกมันว่าเบราว์เซอร์ได้หากพฤติกรรมนั้นแตกต่างกันไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.