เหตุใดจึงไม่ใช้การประเมินแบบขี้เกียจในทุกที่


32

ฉันเพิ่งเรียนรู้ว่าการประเมินผลแบบขี้เกียจทำงานได้อย่างไรและฉันสงสัยว่า: ทำไมจึงไม่ใช้การประเมินแบบขี้เกียจในทุกซอฟต์แวร์ที่ผลิตในปัจจุบัน ทำไมยังใช้การประเมินความกระตือรือร้น


2
นี่คือตัวอย่างของสิ่งที่สามารถเกิดขึ้นได้หากคุณผสมสถานะที่ไม่แน่นอนและการประเมินผลที่ขี้เกียจ alicebobandmallory.com/articles/2011/01/01/…
Jonas Elfström

2
@ JonasElfström: ได้โปรดอย่าสับสนระหว่างสถานะที่ไม่แน่นอนกับการใช้งานอย่างใดอย่างหนึ่งที่เป็นไปได้ สถานะที่ไม่แน่นอนสามารถดำเนินการได้โดยใช้ค่าที่ไม่สิ้นสุดและไม่ต่อเนื่อง จากนั้นคุณไม่มีปัญหาของตัวแปรที่ไม่แน่นอน
จอร์โจ

ในภาษาการเขียนโปรแกรมที่จำเป็น "การประเมินขี้เกียจ" ต้องใช้ความพยายามอย่างมีสติจากโปรแกรมเมอร์ การเขียนโปรแกรมทั่วไปในภาษาที่จำเป็นทำให้มันง่าย แต่จะไม่มีความโปร่งใส คำตอบของคำถามอีกด้านนำมาซึ่งคำถามอีกข้อหนึ่ง: "ทำไมภาษาการเขียนโปรแกรมที่ใช้งานไม่ได้ใช้ทุกที่" และคำตอบในปัจจุบันคือ "ไม่" เป็นเรื่องของสถานการณ์ปัจจุบัน
ร. ว.

2
ภาษาโปรแกรมที่ใช้งานไม่ได้ถูกใช้ทุกที่ด้วยเหตุผลเดียวกับที่เราไม่ได้ใช้ค้อนบนสกรูไม่สามารถแก้ปัญหาทุกอย่างได้อย่างง่ายดายในอินพุตฟังก์ชั่น -> ลักษณะเอาท์พุทตัวอย่างเช่น GUI เหมาะกว่าที่จะแสดงออก .
ALXGTV

นอกจากนี้ยังมีสองคลาสของภาษาโปรแกรมที่ใช้งานได้ (หรืออย่างน้อยทั้งสองอ้างว่าใช้งานได้), ภาษาที่จำเป็นสำหรับการทำงานเช่น Clojure, Scala และการประกาศเช่น Haskell, OCaml
ALXGTV

คำตอบ:


38

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

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

ประการที่สามการประเมินผลที่ขี้เกียจหมายถึงการสูญเสียการควบคุม หากฉันประเมินการอ่านไฟล์จากดิสก์อย่างเกียจคร้าน หรือรับเวลา? ไม่เป็นที่ยอมรับ

การประเมินความกระตือรือร้นสามารถมีประสิทธิภาพมากขึ้นและสามารถควบคุมได้มากขึ้นและถูกแปลงเป็นการประเมินที่ขี้เกียจ ทำไมคุณถึงต้องการประเมินผลแบบขี้เกียจ


10
ขี้เกียจอ่านไฟล์จากดิสก์ที่เป็นจริงที่เรียบร้อยจริงๆ - สำหรับส่วนมากของโปรแกรมที่เรียบง่ายของฉันและสคริปต์ของ Haskell readFileเป็นว่าสิ่งที่ฉันต้องการ นอกจากนี้การแปลงจากความขี้เกียจไปเป็นการประเมินความกระตือรือร้นก็เป็นเรื่องเล็กน้อย
Tikhon Jelvis

3
เห็นด้วยกับคุณทั้งหมดยกเว้นวรรคสุดท้าย การประเมินที่ขี้เกียจนั้นมีประสิทธิภาพมากขึ้นเมื่อมีการปฏิบัติการลูกโซ่และสามารถควบคุมได้มากขึ้นเมื่อคุณต้องการข้อมูลจริง ๆ
texasbruce

4
กฎหมายนักกฎหมายอยากจะมีคำกับคุณเกี่ยวกับ "การสูญเสียการควบคุม" หากคุณเขียนฟังก์ชั่นบริสุทธิ์ที่ทำงานบนประเภทข้อมูลที่ไม่เปลี่ยนรูปการประเมินแบบสันหลังยาวเป็นสิ่งที่มาจากสวรรค์ ภาษาเช่น Haskell นั้นมีพื้นฐานมาจากแนวคิดของความเกียจคร้าน มันยุ่งยากในบางภาษาโดยเฉพาะอย่างยิ่งเมื่อผสมกับรหัส "ไม่ปลอดภัย" แต่คุณกำลังทำให้ดูเหมือนว่าความเกียจคร้านเป็นอันตรายหรือไม่ดีตามค่าเริ่มต้น เป็นเพียง "อันตราย" ในรหัสอันตราย
sara

1
@DeadMG ไม่ได้ถ้าคุณดูแลเกี่ยวกับหรือไม่ยุติรหัสของคุณ ... อะไรhead [1 ..]ทำให้คุณในภาษาที่บริสุทธิ์ประเมินกระหายเพราะใน Haskell จะให้1?
อัฒภาค

1
สำหรับหลาย ๆ ภาษาการใช้การประเมินแบบขี้เกียจจะทำให้เกิดความซับซ้อนน้อยที่สุด บางครั้งจำเป็นต้องมีความซับซ้อนและการประเมินแบบขี้เกียจจะช่วยปรับปรุงประสิทธิภาพโดยรวมโดยเฉพาะอย่างยิ่งหากสิ่งที่ได้รับการประเมินนั้นมีความจำเป็นตามเงื่อนไขเท่านั้น อย่างไรก็ตามทำไม่ดีมันสามารถแนะนำข้อบกพร่องที่ลึกซึ้งหรือยากที่จะอธิบายปัญหาประสิทธิภาพเนื่องจากสมมติฐานไม่ดีเมื่อเขียนรหัส มีการแลกเปลี่ยน
Berin Loritsch

17

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

ในหมายเหตุด้าน Haskell ใช้การประเมิน Lazy สำหรับทุกสิ่ง สิ่งนี้เป็นไปได้เพราะเป็นภาษาที่ใช้งานได้และไม่ได้ใช้สถานะ (ยกเว้นในกรณีพิเศษบางประการที่มีการทำเครื่องหมายไว้อย่างชัดเจน)


ใช่รัฐที่ไม่แน่นอน + การประเมินผลแบบขี้เกียจ = ความตาย ฉันคิดว่าจุดเดียวที่ฉันแพ้ใน SICP สุดท้ายของฉันคือการใช้set!ล่าม Scheme ที่ขี้เกียจ > :(
Tikhon Jelvis

3
"รหัสสันหลังยาวและสถานะสามารถผสมกันได้ไม่ดี": ขึ้นอยู่กับว่าคุณจะใช้สถานะอย่างไร หากคุณใช้งานโดยใช้ตัวแปรที่ไม่แน่นอนที่ใช้ร่วมกันและคุณขึ้นอยู่กับลำดับของการประเมินผลเพื่อให้รัฐของคุณสอดคล้องกันแสดงว่าคุณมีสิทธิ์
จอร์โจ

14

การประเมิน Lazy นั้นไม่ได้ดีกว่าเสมอไป

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

ข้อดีของการประเมินแบบสันหลังยาวคือเมื่อมันช่วยให้คุณเขียนโค้ดที่ชัดเจนขึ้น รับนายกที่ 10 โดยการกรองรายการหมายเลขธรรมชาติที่ไม่มีที่สิ้นสุดและการรับองค์ประกอบที่ 10 ของรายการนั้นเป็นหนึ่งในวิธีที่รัดกุมและชัดเจนที่สุดของการดำเนินการ: (pseudocode)

let numbers = [1,2...]
fun is_prime x = none (map (y-> x mod y == 0) [2..x-1])
let primes = filter is_prime numbers
let tenth_prime = first (take primes 10)

ฉันเชื่อว่ามันค่อนข้างยากที่จะแสดงสิ่งต่าง ๆ อย่างรัดกุมโดยไม่มีความขี้เกียจ

แต่ความขี้เกียจไม่ใช่คำตอบสำหรับทุกสิ่ง สำหรับ starters ความเกียจคร้านไม่สามารถนำมาใช้อย่างโปร่งใสในที่ที่มีสถานะและฉันเชื่อว่า statefulness ไม่สามารถตรวจพบโดยอัตโนมัติได้ ดังนั้นในภาษาส่วนใหญ่ความขี้เกียจจำเป็นต้องทำด้วยตนเองซึ่งทำให้สิ่งต่าง ๆ ชัดเจนน้อยลงและกำจัดข้อดีที่สำคัญอย่างหนึ่งของ eval ขี้เกียจออกไป

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

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


เป็นไปได้ไหมที่คอมไพเลอร์ที่ฉลาดจริง ๆจะลดค่าใช้จ่ายลงอย่างมาก หรือแม้แต่ใช้ประโยชน์จากความเกียจคร้านสำหรับการเพิ่มประสิทธิภาพพิเศษ?
Tikhon Jelvis

3

นี่คือการเปรียบเทียบสั้น ๆ ของข้อดีข้อเสียของการประเมินผลความกระตือรือร้นและขี้เกียจ:

  • การประเมินผลกระตือรือร้น:

    • ค่าโสหุ้ยในการประเมินสิ่งของ

    • การประเมินผลไม่ จำกัด และรวดเร็ว

  • การประเมินผลขี้เกียจ:

    • ไม่มีการประเมินผลที่ไม่จำเป็น

    • ค่าโสหุ้ยการทำบัญชีที่การใช้งานค่า

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

ตอนนี้ลองมาดูซอฟต์แวร์แห่งความเป็นจริง: ฟังก์ชั่นที่คุณเขียนไม่จำเป็นต้องประเมินข้อโต้แย้งทั้งหมด โดยเฉพาะอย่างยิ่งกับฟังก์ชั่นสั้นที่ทันสมัยที่ทำสิ่งเดียวเท่านั้นเปอร์เซ็นต์ของฟังก์ชันที่อยู่ในหมวดหมู่นี้จึงต่ำมาก ดังนั้นการประเมินผลที่ขี้เกียจจะแนะนำค่าใช้จ่ายการทำบัญชีเป็นส่วนใหญ่โดยไม่มีโอกาสที่จะบันทึกอะไรเลย

ดังนั้นการประเมินแบบเกียจคร้านก็ไม่ได้จ่ายเงินโดยเฉลี่ยการประเมินความกระตือรือร้นเป็นสิ่งที่ดีกว่าสำหรับโค้ดสมัยใหม่


1
"ค่าใช้จ่ายในการทำบัญชีทุกครั้งที่ใช้ค่า": ฉันไม่คิดว่าค่าใช้จ่ายในการทำบัญชีนั้นใหญ่กว่าพูดการตรวจสอบการอ้างอิงแบบ null ในภาษาเช่น Java ในทั้งสองกรณีคุณต้องตรวจสอบข้อมูลหนึ่งบิต (ประเมิน / รอดำเนินการกับ null / ไม่ใช่ null) และคุณต้องทำทุกครั้งที่คุณใช้ค่า ดังนั้นใช่มีค่าใช้จ่าย แต่มีน้อย
จอร์โจ

1
"ฟังก์ชั่นที่คุณเขียนไม่จำเป็นต้องประเมินข้อโต้แย้งทั้งหมด": นี่เป็นเพียงตัวอย่างแอปพลิเคชันเดียว โครงสร้างข้อมูลแบบวนซ้ำและไม่มีที่สิ้นสุด? คุณสามารถนำไปใช้กับการประเมินผลที่กระตือรือร้นได้หรือไม่? คุณสามารถใช้ตัววนซ้ำได้ แต่การแก้ปัญหาอาจไม่กระชับเสมอไป แน่นอนคุณอาจไม่พลาดสิ่งที่คุณไม่เคยมีโอกาสใช้อย่างกว้างขวาง
จอร์โจ

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

1
@Giorgio ค่าโสหุ้ยอาจไม่มากสำหรับคุณ แต่เงื่อนไขเป็นหนึ่งในสิ่งที่ซีพียูสมัยใหม่ดูด: สาขาที่มีการพิมพ์ผิดมักจะบังคับให้ส่งไปป์ไลน์ที่สมบูรณ์แล้วละทิ้งการทำงานของ CPU มากกว่าสิบรอบ คุณไม่ต้องการเงื่อนไขที่ไม่จำเป็นในวงในของคุณ การจ่ายสิบรอบพิเศษต่ออาร์กิวเมนต์ของฟังก์ชั่นนั้นแทบจะไม่สามารถยอมรับได้สำหรับโค้ดที่ไวต่อประสิทธิภาพเช่นเดียวกับการเขียนโค้ดในจาวา คุณคิดถูกว่าการประเมินแบบขี้เกียจช่วยให้คุณสามารถใช้กลอุบายที่คุณไม่สามารถทำได้อย่างง่ายดายด้วยการประเมินที่กระตือรือร้น แต่โค้ดส่วนใหญ่ไม่ต้องการเทคนิคเหล่านี้
cmaster

2
นี่ดูเหมือนจะเป็นคำตอบจากประสบการณ์ที่ไม่มีภาษากับการประเมินที่ขี้เกียจ ตัวอย่างเช่นสิ่งที่เกี่ยวกับโครงสร้างข้อมูลที่ไม่มีที่สิ้นสุด?
Andres F.

3

ในฐานะที่เป็น @DeadMG ตั้งข้อสังเกตการประเมินผล Lazy ต้องใช้ค่าใช้จ่ายในการรักษาหนังสือ ซึ่งอาจมีราคาแพงเมื่อเทียบกับการประเมินผลความกระตือรือร้น พิจารณาข้อความนี้:

i = (243 * 414 + 6562 / 435.0 ) ^ 0.5 ** 3

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

ด้วยการประเมินความกระตือรือร้นและคอมไพเลอร์ที่เหมาะสมสูตรจะถูกคำนวณ ณ เวลารวบรวม เครื่องมือเพิ่มประสิทธิภาพส่วนใหญ่จะย้ายการบ้านออกจากลูปใด ๆ ที่เกิดขึ้นหากเหมาะสม

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

โดยทั่วไปเป็นวิธีปฏิบัติที่ดีในการประเมินสิ่งต่าง ๆ ที่เข้าถึงได้บ่อยที่สุดเท่าที่จะทำได้ การประเมิน Lazy ไม่สามารถใช้ได้กับการฝึกนี้ หากคุณจะเข้าถึงบางสิ่งการประเมินที่ขี้เกียจจะทำคือเพิ่มค่าใช้จ่าย ค่าใช้จ่าย / ผลประโยชน์ของการใช้การประเมินแบบขี้เกียจลดลงเนื่องจากรายการที่เข้าถึงนั้นมีโอกาสน้อยที่จะเข้าถึง

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

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


1
คุณดูเหมือนจะเถียงจากประสบการณ์ที่ไม่มีประสบการณ์ ฉันแนะนำให้คุณอ่านบทความเรื่อง "Why Functional Programming Matters" โดย Wadler มันอุทิศส่วนสำคัญที่อธิบายถึงสาเหตุของการประเมินผลแบบขี้เกียจ (คำใบ้: มันมีส่วนเกี่ยวข้องกับประสิทธิภาพการเพิ่มประสิทธิภาพ แต่เนิ่น ๆ หรือ "การโหลดข้อมูลที่เข้าถึงไม่บ่อย" และทุกสิ่งที่เกี่ยวข้องกับโมดูล)
Andres F.

@AndresF ฉันได้อ่านกระดาษที่คุณอ้างถึง ฉันเห็นด้วยกับการใช้การประเมินผลแบบขี้เกียจในกรณีเช่นนี้ การประเมินก่อนอาจไม่เหมาะสม แต่ฉันจะโต้แย้งกลับต้นไม้ย่อยสำหรับการย้ายที่เลือกอาจมีประโยชน์อย่างมีนัยสำคัญหากสามารถเพิ่มการเคลื่อนไหวเพิ่มเติมได้อย่างง่ายดาย อย่างไรก็ตามการสร้างฟังก์ชันนั้นอาจเป็นการเพิ่มประสิทธิภาพก่อนวัยอันควร นอกการเขียนโปรแกรมการทำงานฉันมีปัญหาสำคัญเกี่ยวกับการใช้การประเมินผลแบบขี้เกียจและความล้มเหลวในการใช้การประเมินผลแบบขี้เกียจ มีรายงานค่าใช้จ่ายประสิทธิภาพที่สำคัญซึ่งเป็นผลมาจากการประเมินที่ขี้เกียจในการเขียนโปรแกรมการทำงาน
BillThor

2
เช่น? มีรายงานของค่าใช้จ่ายประสิทธิภาพที่สำคัญเมื่อใช้การประเมินความกระตือรือร้นเช่นกัน (ค่าใช้จ่ายในรูปแบบของการประเมินผลที่ไม่จำเป็นอย่างใดอย่างหนึ่งเช่นเดียวกับโปรแกรมไม่เลิกจ้าง) มีค่าใช้จ่ายสำหรับคุณสมบัติที่ใช้งานผิดพลาดอื่น ๆ ลองนึกถึงมัน ความเป็นโมดูลเองอาจมีค่าใช้จ่าย ปัญหาคือว่ามันคุ้มค่า
Andres F.

3

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

[True, True, True, ... False]

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

foldr (&&) True [True, True, True, ... False] 
> 0.27 secs

ในกรณีนี้การพับที่ด้านขวาจะช้ากว่าการพับแบบ จำกัด ทางซ้ายซึ่งไม่ได้ใช้การประเมินแบบขี้เกียจ:

foldl' (&&) True [True, True, True, ... False] 
> 0.09 secs

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


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