การใช้คำตอบที่ดีของ jbapple เกี่ยวกับการreplicateใช้riffing แทนreplicateA(ซึ่งreplicateสร้างขึ้นบน) แทนที่จะทำตามขั้นตอนต่อไปนี้:
--Unlike fromList, one needs the length explicitly.
myFromList :: Int -> [b] -> Seq b
myFromList l xs = flip evalState xs $ Seq.replicateA l go
where go = do
(y:ys) <- get
put ys
return y
myFromList(ในรุ่นเล็กน้อยมีประสิทธิภาพมากขึ้น) เป็นที่เรียบร้อยแล้วกำหนดและใช้ภายในในData.Sequenceการสร้างต้นไม้นิ้วที่มีผลการทุกประเภท
โดยทั่วไปแล้วสัญชาตญาณของreplicateAเรื่องง่าย replicateAถูกสร้างขึ้นที่ด้านบนของฟังก์ชั่นapplicativeTree applicativeTreeรับต้นไม้ขนาดหนึ่งชิ้นmและสร้างต้นไม้ที่มีความสมดุลซึ่งบรรจุnสำเนาของสิ่งนี้ เคสสำหรับnมากถึง 8 ( Deepนิ้วเดียว) นั้นเขียนโค้ดแบบยาก อะไรก็ตามที่อยู่เหนือสิ่งนี้และมันจะเรียกตัวเองซ้ำ ๆ องค์ประกอบ "การใช้งาน" เป็นเพียงการแทรกการสร้างต้นไม้ที่มีเอฟเฟกต์เกลียวผ่านเช่นในกรณีของรหัสข้างต้นรัฐ
goฟังก์ชั่นซึ่งถูกจำลองเป็นเพียงการกระทำที่ได้รับสถานะปัจจุบันปรากฏองค์ประกอบปิดด้านบนไปและแทนที่ส่วนที่เหลือ ในการร้องขอแต่ละครั้งจะมีขั้นตอนเพิ่มเติมในรายการที่ให้ไว้เป็นอินพุต
หมายเหตุที่เป็นรูปธรรมมากขึ้น
main = print (length (show (Seq.fromList [1..10000000::Int])))
ในการทดสอบแบบง่าย ๆ สิ่งนี้ให้ผลการปฏิบัติที่น่าสนใจ หน้าที่หลักข้างต้นวิ่งเกือบ 1/3 ที่ต่ำกว่าด้วย myFromList fromListกว่าด้วย ในทางกลับกันmyFromListใช้ฮีปคงที่ 2MB ในขณะที่มาตรฐานfromListใช้สูงสุด 926MB 926MB นั้นเกิดขึ้นจากต้องเก็บรายชื่อทั้งหมดไว้ในหน่วยความจำพร้อมกัน ในขณะเดียวกันการแก้ปัญหาด้วยmyFromListสามารถที่จะใช้โครงสร้างในแบบสตรีมมิ่งขี้เกียจ ปัญหาเกี่ยวกับความเร็วเป็นผลมาจากความจริงที่ว่าmyFromListจะต้องดำเนินการจัดสรรเป็นสองเท่าโดยประมาณfromList. เราสามารถกำจัดการจัดสรรเหล่านั้นได้ด้วยการย้ายไปที่ Monad ที่เปลี่ยนรูปแบบ CPS แต่ผลลัพธ์นั้นจะทำให้หน่วยความจำมีมากขึ้นในเวลาใดก็ตามเนื่องจากการสูญเสียความขี้เกียจนั้นต้องผ่านรายการในลักษณะที่ไม่ได้สตรีม
ในทางตรงกันข้ามถ้าแทนที่จะบังคับให้ลำดับทั้งหมดด้วยการแสดงฉันจะย้ายไปที่การแยกส่วนหัวหรือองค์ประกอบสุดท้ายmyFromListนำเสนอการชนะที่ยิ่งใหญ่ขึ้นทันที - การแยกองค์ประกอบส่วนหัวนั้นเกือบจะในทันทีและการแยกองค์ประกอบสุดท้ายคือ 0.8s . ในขณะเดียวกันด้วยมาตรฐานการfromListแยกส่วนหัวหรือองค์ประกอบสุดท้ายใช้เวลาประมาณ 2.3 วินาที
นี่คือรายละเอียดทั้งหมดและเป็นผลมาจากความบริสุทธิ์และความเกียจคร้าน ในสถานการณ์ที่มีการกลายพันธุ์และการเข้าถึงแบบสุ่มฉันคิดว่าreplicateวิธีแก้ปัญหานั้นจะดีกว่าอย่างเคร่งครัด
อย่างไรก็ตามมันทำให้เกิดคำถามว่ามีวิธีการเขียนapplicativeTreeเช่นmyFromListนี้ว่ามีประสิทธิภาพมากขึ้นอย่างเคร่งครัด ปัญหาคือฉันคิดว่าการดำเนินการสมัครจะดำเนินการในลำดับที่แตกต่างจากต้นไม้ที่ถูกสำรวจโดยธรรมชาติ แต่ฉันไม่ได้ทำงานอย่างเต็มที่ผ่านวิธีการทำงานนี้หรือหากมีวิธีการแก้ปัญหานี้