การสาธิตการรวบรวมขยะเร็วกว่าการจัดการหน่วยความจำด้วยตนเอง


23

ฉันได้อ่านในหลาย ๆ ที่ (heck ฉันยังเขียนด้วยตัวเอง) ว่าการเก็บขยะอาจทำได้เร็วกว่าการจัดการหน่วยความจำด้วยตนเอง

อย่างไรก็ตามการแสดงนั้นยากกว่าที่จะบอก
ฉันไม่เคยเห็นรหัสใด ๆ ที่แสดงให้เห็นถึงผลกระทบจากการกระทำนี้

ใครบ้างมีรหัส (หรือรู้ว่าฉันสามารถหาได้ที่ไหน) ที่แสดงถึงข้อได้เปรียบด้านประสิทธิภาพนี้?


5
ปัญหาของ GC ก็คือการใช้งานส่วนใหญ่ไม่ได้กำหนดไว้ดังนั้นการวิ่ง 2 ครั้งอาจมีผลลัพธ์ที่แตกต่างกันอย่างมากไม่ต้องพูดถึงมันเป็นการยากที่จะแยกตัวแปรที่เหมาะสมเพื่อเปรียบเทียบ
ratchet freak

@ ratchetfreak: ถ้าคุณรู้ตัวอย่างใด ๆ ที่เร็วขึ้น (พูด) 70% ของเวลานั่นก็เป็นเรื่องดีสำหรับฉันเช่นกัน ต้องมีบางวิธีที่จะเปรียบเทียบทั้งสองในแง่ของการส่งผ่านอย่างน้อย (แฝงอาจจะไม่ทำงาน)
Mehrdad

1
นี่เป็นเรื่องยุ่งยากเล็กน้อยเพราะคุณสามารถทำสิ่งใด ๆ ด้วยตนเองเพื่อให้ GC ได้เปรียบเหนือสิ่งที่คุณทำด้วยตนเอง อาจดีกว่าที่จะ จำกัด สิ่งนี้ไว้ที่ "มาตรฐาน" เครื่องมือจัดการหน่วยความจำด้วยตนเอง (malloc () / ฟรี (), พอยน์เตอร์ที่เป็นเจ้าของ, พอยน์เตอร์ที่ใช้ร่วมกับ refcount, พอยน์พอยน์, ไม่มีตัวจัดสรรแบบกำหนดเอง)? หรือถ้าคุณอนุญาตให้ผู้จัดสรรที่กำหนดเอง (ซึ่งอาจเป็นจริงหรือสมจริงน้อยกว่าขึ้นอยู่กับชนิดของโปรแกรมเมอร์ที่คุณคิด) ให้วางข้อ จำกัด เกี่ยวกับความพยายามที่จะใส่ลงในตัวจัดสรรเหล่านั้น มิฉะนั้นกลยุทธ์ด้วยตนเอง "คัดลอกสิ่งที่ GC ทำในกรณีนี้" อย่างน้อยก็เร็วเท่ากับ GC

1
โดย "คัดลอกสิ่งที่ GC ทำ" ฉันไม่ได้หมายถึง "สร้าง GC ของคุณเอง" (แม้ว่าโปรดทราบว่านี่เป็นไปได้ในทางทฤษฎีใน C ++ 11 ขึ้นไปซึ่งแนะนำการสนับสนุนเสริมสำหรับ GC) ฉันหมายถึงอย่างที่ฉันเคยพูดไว้ก่อนหน้านี้ในความคิดเห็นเดียวกันว่า "ทำในสิ่งที่ทำให้ GC มีความได้เปรียบเหนือสิ่งที่คุณทำด้วยตนเอง" ตัวอย่างเช่นถ้าการบดอัดคล้ายกับ Cheney ช่วยให้แอปพลิเคชันนี้มีจำนวนมากคุณอาจใช้รูปแบบการจัดสรร + การบดอัดที่คล้ายกันด้วยตัวชี้สมาร์ทที่กำหนดเองเพื่อจัดการการแก้ไขตัวชี้ นอกจากนี้ด้วยเทคนิคต่างๆเช่น shadow stack คุณสามารถทำการค้นหารูทใน C หรือ C ++ ได้โดยเสียค่าใช้จ่ายในการทำงานพิเศษ

1
@Ike: ไม่เป็นไร ดูว่าทำไมฉันถามคำถาม นั่นคือประเด็นทั้งหมดของคำถามของฉัน - ผู้คนเกิดขึ้นพร้อมกับคำอธิบายทุกประเภทที่ควรสมเหตุสมผล แต่ทุกคนก็สะดุดเมื่อคุณขอให้พวกเขาสาธิตให้เห็นว่าสิ่งที่พวกเขาพูดนั้นถูกต้องในทางปฏิบัติ ประเด็นทั้งหมดของคำถามนี้คือการทำเพียงครั้งเดียวและสำหรับทุกคนแสดงให้เห็นว่าสิ่งนี้สามารถเกิดขึ้นได้จริงในทางปฏิบัติ
Mehrdad

คำตอบ:


26

ดูhttp://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspxและติดตามลิงก์ทั้งหมดเพื่อดู Rico Mariani vs Raymond Chen (โปรแกรมเมอร์ที่มีความสามารถทั้งคู่ที่ Microsoft) ต่อสู้กับมัน . เรย์มอนด์จะปรับปรุงสิ่งที่ไม่มีการจัดการเปอร์โตริโกจะตอบสนองโดยการปรับสิ่งเดียวกันในสิ่งที่ได้รับการจัดการ

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


+1 สำหรับอ้างเป็นตัวอย่างที่เกิดขึ้นจริงด้วยรหัส :) แม้จะใช้ที่เหมาะสมของภาษา C ++ โครงสร้าง (เช่นswap) ไม่ยากและอาจจะช่วยให้คุณมีค่อนข้างง่ายประสิทธิภาพฉลาด ...
Mehrdad

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

ผมคัดลอกรหัสเรย์มอนด์ที่นี่และเปรียบเทียบผมเขียนรุ่นของตัวเองที่นี่ ไฟล์ ZIP ที่มีไฟล์ข้อความที่นี่ ในคอมพิวเตอร์ของฉันการทำงานของฉันใน 14 ms และการทำงานของ Raymond ใน 21 ms ยกเว้นว่าฉันทำอะไรผิดพลาด (ซึ่งเป็นไปได้) รหัส 215 บรรทัดของเขานั้นช้ากว่าการใช้ 48 บรรทัดของฉันถึง 50% แม้จะไม่ได้ใช้ไฟล์ที่แม็พหน่วยความจำหรือพูลหน่วยความจำที่กำหนดเองก็ตาม ของฉันมีค่าครึ่งหนึ่งตราบเท่าที่เวอร์ชั่น C # ฉันทำผิดหรือคุณสังเกตสิ่งเดียวกันหรือไม่?
Mehrdad

1
@ Mehrdad การดึงสำเนา gcc เก่า ๆ บนแล็ปท็อปนี้ฉันสามารถรายงานได้ว่าทั้งรหัสของคุณและความตั้งใจของเขานั้นไม่ได้ทำอะไรเลย ความจริงที่ว่าฉันไม่ได้อยู่บน Windows อาจอธิบายได้ว่า แต่สมมติว่าตัวเลขและรหัสของคุณถูกต้อง พวกเขาทำเช่นเดียวกันในคอมไพเลอร์และคอมพิวเตอร์อายุสิบปีหรือไม่? (ดูเวลาที่เขียนบล็อก) อาจจะไม่ใช่ ลองสมมติว่าพวกเขาเป็น (โปรแกรมเมอร์ C) ไม่ทราบวิธีการใช้ C ++ อย่างถูกต้อง ฯลฯ เรามีอะไรเหลืออยู่บ้าง?
btilly

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

5

กฎง่ายๆคือไม่มีอาหารกลางวันฟรี

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

GC เป็นกรณีพิเศษของการจัดการหน่วยความจำด้วยตนเอง

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


1
นั่นทำให้ฉันไม่มีเหตุผล เพื่อให้ตัวอย่างที่เป็นรูปธรรมสองสามข้อ: 1) ตัวปันส่วนและเขียนอุปสรรคในการผลิต GC เป็นแอสเซมเบลอร์ที่เขียนด้วยมือเพราะ C ไม่มีประสิทธิภาพมากเกินไปดังนั้นคุณจะเอาชนะสิ่งนั้นจาก C ได้อย่างไรและ 2) การกำจัดหางแบบหางเป็นตัวอย่างของการเพิ่มประสิทธิภาพ ทำในภาษาระดับสูง (ฟังก์ชั่น) ที่ไม่ได้ทำโดยคอมไพเลอร์ C ดังนั้นจึงไม่สามารถทำได้ใน C. การเดินสแต็กเป็นอีกตัวอย่างหนึ่งของบางสิ่งที่ทำต่ำกว่าระดับ C โดยภาษาระดับสูง
Jon Harrop

2
1) ฉันต้องดูรหัสเฉพาะเพื่อแสดงความคิดเห็น แต่ถ้าผู้จัดสรรมือเขียน / อุปสรรคในแอสเซมเบลอร์เร็วขึ้นให้ใช้แอสเซมเบลอร์ที่เขียนด้วยมือ ไม่แน่ใจว่าจะทำอย่างไรกับ GC 2) ดูที่นี่: stackoverflow.com/a/9814654/441099ประเด็นก็คือไม่ใช่ว่าภาษาที่ไม่ใช่ GC บางอย่างสามารถกำจัดการเรียกซ้ำแบบหางสำหรับคุณได้หรือไม่ ประเด็นก็คือคุณสามารถเปลี่ยนรหัสของคุณให้เร็วหรือเร็วกว่าได้ การคอมไพเลอร์ของภาษาเฉพาะสามารถทำสิ่งนี้ให้คุณโดยอัตโนมัติได้หรือไม่ ในสิ่งที่เป็นนามธรรมที่ต่ำพอคุณสามารถทำสิ่งนี้ได้ด้วยตัวเองหากคุณต้องการ
Guy Sirton

1
ตัวอย่างการเรียกแบบหางนั้นใน C ใช้งานได้สำหรับกรณีพิเศษของฟังก์ชันที่เรียกตัวเองเท่านั้น C ไม่สามารถจัดการกรณีทั่วไปของฟังก์ชั่นหางเรียกซึ่งกันและกัน การปล่อยให้แอสเซมเบลอร์และสมมติว่าไม่มีเวลา จำกัด สำหรับการพัฒนาคือ Turing tarpit
Jon Harrop

3

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

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

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


ถ้ามันง่ายที่จะสร้างตัวอย่างเทียมคุณจะแสดงตัวอย่างง่ายๆได้หรือไม่?
Mehrdad

1
@ Mehrdad เขาอธิบายอย่างง่าย ๆ เขียนโปรแกรมที่เวอร์ชัน GC ล้มเหลวในการรันขยะก่อนออกจากโปรแกรม รุ่นที่มีการจัดการหน่วยความจำด้วยตนเองจะช้าลงเพราะเป็นการติดตามและการปลดปล่อยเนื้อหาอย่างชัดเจน
btilly

3
@btilly: "เขียนโปรแกรมที่เวอร์ชัน GC ล้มเหลวในการเรียกใช้ขยะก่อนออก" ... ล้มเหลวในการทำการเก็บขยะในสถานที่แรกคือหน่วยความจำรั่วเนื่องจากการขาดการทำงาน GC ไม่ปรับปรุงประสิทธิภาพการทำงานเนื่องจากการปรากฏตัวของประชาคมโลกเป็นคนแรก! มันเหมือนกับการโทรabort()ใน C ++ ก่อนที่โปรแกรมจะออก เป็นการเปรียบเทียบที่ไร้ความหมาย คุณไม่ได้แม้แต่เก็บขยะคุณแค่ปล่อยให้หน่วยความจำรั่ว คุณไม่สามารถพูดได้ว่าการรวบรวมขยะเร็วขึ้น (หรือช้ากว่า) หากคุณไม่ใช่การรวบรวมขยะเพื่อเริ่มต้น ...
Mehrdad

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

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

2

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

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


2

เร็วกว่าน่าสงสัย อย่างไรก็ตามมันอาจเร็วเป็นพิเศษมองไม่เห็นหรือเร็วกว่านั้นหากรองรับฮาร์ดแวร์ มีการออกแบบเช่นนั้นสำหรับเครื่อง LISP เมื่อนานมาแล้ว หนึ่งสร้าง GC ในระบบย่อยหน่วยความจำของฮาร์ดแวร์เช่นที่ CPU หลักไม่ทราบว่ามันอยู่ที่นั่น เช่นเดียวกับการออกแบบในภายหลังหลายอย่าง GC ทำงานพร้อมกันกับตัวประมวลผลหลักโดยไม่จำเป็นต้องหยุดชั่วคราว การออกแบบที่ทันสมัยยิ่งขึ้นคือเครื่อง Azul Systems Vega 3 ที่รันโค้ด Java ได้เร็วกว่า JVM โดยใช้โปรเซสเซอร์ที่สร้างขึ้นตามวัตถุประสงค์และ GC ที่หยุดชั่วคราว Google หากคุณต้องการทราบว่า GC (หรือ Java) รวดเร็วแค่ไหน


2

ฉันได้ทำไม่น้อยในการทำงานเกี่ยวกับเรื่องนี้และอธิบายบางส่วนของมันนี่ ฉันเปรียบเทียบ Boehm GC ใน C ++, การจัดสรรโดยใช้mallocแต่ไม่ทำให้ว่าง, จัดสรรและเพิ่มการใช้freeและ GC แบบมาร์คที่สร้างขึ้นเองที่เขียนใน C ++ ทั้งหมดเทียบกับหุ้น OCaml ของ OCaml ทำงานเป็นตัวแก้รายการ n-queens GCam ของ OCaml นั้นเร็วกว่าในทุกกรณี โปรแกรม C ++ และ OCaml ถูกเขียนอย่างจงใจเพื่อทำการจัดสรรแบบเดียวกันในลำดับเดียวกัน

แน่นอนคุณสามารถเขียนโปรแกรมใหม่เพื่อแก้ปัญหาโดยใช้จำนวนเต็ม 64- บิตเท่านั้นและไม่มีการจัดสรร แม้ว่าเร็วกว่าที่จะกำจัดจุดของการฝึกซ้อม (ซึ่งก็คือการทำนายประสิทธิภาพของอัลกอริทึม GC ใหม่ที่ฉันกำลังทำงานโดยใช้ต้นแบบที่สร้างขึ้นใน C ++)

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


+1 เราจะดูและเรียกใช้รหัสเปรียบเทียบได้จากที่ไหน?
Mehrdad

รหัสนี้กระจัดกระจายเกี่ยวกับสถานที่ ฉันโพสต์รุ่นพื้นที่ทำเครื่องหมายไว้ที่นี่: groups.google.com/d/msg/…
Jon Harrop

1
มีผลลัพธ์สำหรับทั้งเธรดที่ปลอดภัยและไม่ปลอดภัยอยู่ในนั้น
Jon Harrop

1
@ Mehrdad: "คุณกำจัดแหล่งที่มาของข้อผิดพลาดที่อาจเกิดขึ้น?" ใช่. OCaml มีรูปแบบการรวบรวมที่ง่ายมากโดยไม่มีการเพิ่มประสิทธิภาพเช่นการวิเคราะห์แบบหลบหนี การเป็นตัวแทนของการปิดของ OCaml นั้นช้ากว่าโซลูชัน C ++ มากดังนั้นจึงควรใช้การกำหนดเองList.filterตามที่ C ++ ทำ แต่ใช่คุณค่อนข้างถูกต้องที่การปฏิบัติการ RC บางอย่างอาจถูกกำจัดออกไป อย่างไรก็ตามปัญหาที่ใหญ่ที่สุดที่ฉันเห็นในป่าคือผู้คนไม่มีเวลาที่จะทำการปรับให้เหมาะสมด้วยตนเองบนฐานรหัสอุตสาหกรรมขนาดใหญ่
Jon Harrop

2
ใช่แล้ว ไม่มีความพยายามเพิ่มเติมในการเขียน แต่การเขียนรหัสไม่ใช่คอขวดด้วย C ++ การบำรุงรักษารหัสคือ การบำรุงรักษาโค้ดด้วยความซับซ้อนที่เกิดขึ้นแบบนี้เป็นฝันร้าย รหัสฐานอุตสาหกรรมส่วนใหญ่เป็นล้านบรรทัดของรหัส คุณไม่ต้องการที่จะจัดการกับสิ่งนั้น ฉันเคยเห็นผู้คนเปลี่ยนทุกอย่างเป็นshared_ptrเพียงแค่แก้ไขข้อบกพร่องที่เกิดขึ้นพร้อมกัน รหัสช้าลงมาก แต่เอาล่ะตอนนี้ใช้ได้แล้ว
Jon Harrop

-1

ตัวอย่างเช่นจำเป็นต้องมีรูปแบบการจัดสรรหน่วยความจำด้วยตนเองที่ไม่ดี

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

ตอนนี้พิจารณาจัดสรรคู่มือที่ใช้กลไกการจัดสรรเช่นเดียวกับGCและมีการโทรเพียงชุดกันหน่วยความจำที่เป็นอิสระโดยวิธีการเช่นเดียวกับfree() GCไม่มีเฟสสแกนและไม่มีวิธีอื่นใด มันต้องใช้เวลาน้อยลง


2
ตัวเก็บรวบรวมขยะสามารถเพิ่มวัตถุจำนวนมากได้โดยไม่ต้องใส่หน่วยความจำให้อยู่ในสถานะที่มีประโยชน์หลังจากนั้น พิจารณางานที่จะลบออกจากรายการลำดับรายการทั้งหมดที่ตรงตามเกณฑ์ที่กำหนด การลบรายการเดียวออกจากรายการ N-item คือ O (N); การลบรายการ M จากรายการ N หนึ่งรายการต่อครั้งคือ O (M * N) การลบรายการทั้งหมดที่ตรงตามเกณฑ์ในการส่งผ่านครั้งเดียวผ่านทางรายการคือ O (1)
supercat

@supercat: freeยังสามารถรวบรวมชุด (และแน่นอนว่าการลบรายการทั้งหมดที่ตรงตามเกณฑ์ยังคงเป็น O (N) หากเพียงเพราะการสำรวจเส้นทางรายการเอง)
MSalters

การลบรายการทั้งหมดที่ตรงตามเกณฑ์คืออย่างน้อย O (N) คุณถูกต้องที่freeสามารถทำงานในโหมดรวบรวมชุดหากรายการหน่วยความจำแต่ละรายการมีการตั้งค่าสถานะที่เกี่ยวข้องแม้ว่า GC ยังสามารถออกมาข้างหน้าในบางสถานการณ์ หากมีการอ้างอิง M ซึ่งระบุ L รายการที่แตกต่างจากชุดของ N สิ่งเวลาในการลบการอ้างอิงทุกครั้งที่ไม่มีการอ้างอิงและรวมส่วนที่เหลือคือ O (M) มากกว่า O (N) หากมีพื้นที่เพิ่มเติม M ให้ค่าคงที่ของการปรับอาจมีขนาดค่อนข้างเล็ก ยิ่งไปกว่านั้นการทำให้กะทัดรัดในระบบ GC ที่ไม่สแกนต้องใช้ ...
supercat

@supercat: เอาล่ะแน่นอนว่าไม่ใช่ O (1) ในประโยคสุดท้ายของคุณในสถานะความคิดเห็นแรก
MSalters

1
@Malters: "และสิ่งที่จะป้องกันไม่ให้แผนการกำหนดจากสถานรับเลี้ยงเด็ก?" ไม่มีอะไร ตัวติดตามขยะของ OCaml เป็นตัวกำหนดและใช้เรือนเพาะชำ แต่มันไม่ใช่ "คู่มือ" และฉันคิดว่าคุณใช้คำว่า "เด็ดขาด" ในทางที่ผิด
Jon Harrop
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.