ข้อแลกเปลี่ยนระหว่าง lazy กับ eager
ทราบว่าเมื่อใดการประเมินแบบ lazy ช่วยหรือทำให้ช้าลง
ข้อแลกเปลี่ยนระหว่าง lazy กับ eager เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
ไม่มีอาหารกลางวันฟรี
แบบขี้เกียจไม่ได้เร็วกว่าเสมอไป โดยแลกการจัดสรรหน่วยความจำล่วงหน้ากับค่าใช้จ่ายเมื่อเข้าถึงแต่ละครั้ง และเปลี่ยนเวลาที่ผลข้างเคียงทำงาน การเข้าใจข้อแลกเปลี่ยนเหล่านี้ช่วยให้คุณเลือกได้อย่างถูกต้อง
แบบขี้เกียจได้เปรียบ: ใช้ข้อมูลเพียงบางส่วน
ต้องการเพียงบางส่วนของการแปลงข้อมูลขนาดใหญ่มาก — แบบขี้เกียจจึงข้ามส่วนที่เหลือ:
let data = Array(1...1_000_000)
let top = data.lazy.map { $0 * 2 }.prefix(3)
print(Array(top)) // [2, 4, 6] -- 999,997 transforms skippedeager ได้เปรียบ: ใช้ซ้ำทั้งหมด
หากคุณวนซ้ำผลลัพธ์หลายครั้ง eager จะคำนวณเพียงครั้งเดียว ส่วนแบบขี้เกียจจะคำนวณใหม่ทุกครั้งที่วนซ้ำ:
let doubled = [1, 2, 3].map { $0 * 2 } // computed once
print(doubled.reduce(0, +)) // 12
print(doubled.max()!) // 6 -- no recomputeแบบขี้เกียจคำนวณใหม่
มุมมองแบบขี้เกียจเดียวกันจะทำงานซ้ำทุกครั้งที่วนซ้ำ:
var work = 0
let view = [1, 2, 3].lazy.map { (n: Int) -> Int in work += 1; return n }
_ = view.reduce(0, +)
_ = view.max()
print(work) // 6 -- transformed twiceค่าใช้จ่ายต่อสมาชิก
แต่ละขั้นตอนแบบขี้เกียจจะห่อ sequence ไว้ในอีก type หนึ่ง และเรียกผ่าน closures ทีละสมาชิก สำหรับอาร์เรย์ขนาดเล็กมาก ค่าใช้จ่ายนี้อาจมากกว่าหน่วยความจำที่ประหยัดได้
อาร์เรย์ขนาดเล็ก ใช้ eager ได้
สำหรับสมาชิกไม่กี่รายการที่ใช้ทั้งหมด ควรเลือก eager แบบธรรมดา — โค้ดเรียบง่ายกว่า และการจัดสรรหน่วยความจำก็มีค่าใช้จ่ายเล็กน้อย:
let nums = [3, 1, 2]
let sorted = nums.map { $0 + 1 }.sorted()
print(sorted) // [2, 3, 4]เวลาของผลข้างเคียงแตกต่างกัน
เมื่อใช้แบบขี้เกียจ เนื้อความของ closure จะทำงานช้ากว่าบรรทัดที่กำหนด closure นั้นไว้ หลีกเลี่ยงการพึ่งพาผลข้างเคียงภายในการแปลงแบบขี้เกียจ:
var log: [Int] = []
let v = [1, 2].lazy.map { (n: Int) -> Int in log.append(n); return n }
print(log) // [] -- nothing ran yet
_ = Array(v)
print(log) // [1, 2]การดำเนินการที่บังคับให้ประเมินทันที
การดำเนินการบางอย่างจำเป็นต้องอ่าน sequence ทั้งหมดอยู่แล้ว ดังนั้นแบบขี้เกียจจึงไม่ให้ประโยชน์ในกรณีนี้:
let nums = Array(1...10)
print(nums.lazy.map { $0 * 2 }.sorted()) // sorted must see all -> [2,4,...,20]
print(nums.lazy.map { $0 }.count) // count walks everythingแบบขี้เกียจร่วมกับการตรวจสอบสมาชิก
การดำเนินการแบบหยุดทันทีเมื่อได้คำตอบ เช่น contains(where:) จะได้ประโยชน์จากแบบขี้เกียจเมื่อข้อมูลขาเข้ามีขนาดใหญ่:
let big = Array(1...1_000_000)
let found = big.lazy.map { $0 * 2 }.contains { $0 == 8 }
print(found) // true -- stops at element 4รายการตรวจสอบเพื่อการตัดสินใจ
ใช้แบบขี้เกียจเมื่อ: แหล่งข้อมูลมีขนาดใหญ่ AND คุณเก็บไว้เพียงบางส่วน (คำนำหน้า / รายการแรก / การตรวจสอบสมาชิก) AND คุณวนซ้ำเพียงครั้งเดียว ใช้ eager เมื่อ: อาร์เรย์มีขนาดเล็ก คุณนำผลลัพธ์กลับมาใช้ซ้ำ หรือความอ่านง่ายสำคัญกว่าการปรับประสิทธิภาพเพียงเล็กน้อย
let huge = Array(1...100_000)
let first = huge.lazy.filter { $0 % 9973 == 0 }.first
print(first!) // 9973วัดผล อย่าเดา
สัญชาตญาณด้านประสิทธิภาพมักไม่ถูกต้อง เมื่อเรื่องนี้สำคัญ ให้ทดสอบประสิทธิภาพทั้งสองรูปแบบด้วยข้อมูลที่ใกล้เคียงการใช้งานจริงก่อนตัดสินใจใช้แบบขี้เกียจ
let nums = Array(1...50)
let eager = nums.filter { $0 > 25 }.count
let lazyC = nums.lazy.filter { $0 > 25 }.count
print(eager == lazyC) // true -- same answer, profile for speedตรวจสอบอย่างรวดเร็ว
เมื่อใดจึงควรเลือก eager แทนแบบขี้เกียจ
สรุป
คุณได้เรียนรู้ข้อแลกเปลี่ยนต่าง ๆ:
- แบบขี้เกียจได้เปรียบเมื่อแหล่งข้อมูลมีขนาดใหญ่ และใช้ข้อมูลเพียงบางส่วนในการวนซ้ำครั้งเดียว
- eager ได้เปรียบสำหรับอาร์เรย์ขนาดเล็กและผลลัพธ์ที่นำกลับมาใช้ซ้ำ (แบบขี้เกียจจะคำนวณใหม่)
- ผลข้างเคียงในการแปลงแบบขี้เกียจจะทำงานภายหลัง — หลีกเลี่ยงการพึ่งพาผลข้างเคียงเหล่านั้น
- วัดผลก่อนปรับประสิทธิภาพ
ถัดไป: การสร้าง sequence แบบขี้เกียจที่กำหนดเอง
เรียนรู้ Swift ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 122
- บทเรียน
- 409
คำถามที่พบบ่อย
บทเรียน “ข้อแลกเปลี่ยนระหว่าง lazy กับ eager” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ข้อแลกเปลี่ยนระหว่าง lazy กับ eager” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ข้อแลกเปลี่ยนระหว่าง lazy กับ eager”
ทราบว่าเมื่อใดการประเมินแบบ lazy ช่วยหรือทำให้ช้าลง คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ข้อแลกเปลี่ยนระหว่าง lazy กับ eager” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คุณสมบัติ lazy
- map และ filter แบบ lazy
- ข้อแลกเปลี่ยนระหว่าง lazy กับ eager
- การสร้างลำดับแบบ lazy ที่กำหนดเอง