เหตุใดการใช้คำสั่ง Debug จึงทำให้โค้ดทำงานช้ามาก

ฉันมีวงนี้

        // go through each alumni
        foreach (esDL.Alumni currAlumni in allAlumnis)
        {
            ... loop logic

        }

การวิ่งนี้เกือบจะทันที

เมื่อฉันใส่คำสั่งติดตามหรือแก้ไขข้อบกพร่องเช่นนั้น...

        foreach (esDL.Alumni currAlumni in allAlumnis)
        {
            ... same loop logic

            Trace.WriteLine("hi");
            Trace.Indent();
            Trace.WriteLine("written");

        }

สิ่งนี้ทำให้สิ่งต่าง ๆ ช้าลงอย่างมาก ทั้งสำหรับการติดตามหรือดีบัก

ทำไมเป็นอย่างนั้น? มีวิธีป้องกันสิ่งนี้หรือไม่?

ฉันแนบเฉพาะ Listener เริ่มต้นเท่านั้น

แก้ไข - จากการทดสอบเพิ่มเติมฉันพบว่า Trace.Indent ทำให้มันช้าลงมาก แต่การมี WriteLine เพียงอย่างเดียวยังคงลดประสิทธิภาพลงอย่างมาก เกิดอะไรขึ้นกับวิธีการเยื้อง?


person Diskdrive    schedule 17.03.2011    source แหล่งที่มา
comment
คุณได้กำหนดค่า Listener การติดตามประเภทใดไว้   -  person harpo    schedule 17.03.2011
comment
เพียง defaultTraceListener   -  person Diskdrive    schedule 17.03.2011
comment
อุ๊ย คุณพูดแบบนั้น แล้วจะช้ากว่ามากขนาดไหน? เช่นเดียวกับการวัดหรือเพียงแค่การสังเกต?   -  person harpo    schedule 17.03.2011
comment
แค่ข้อสังเกต ฉันมี 2,000 แถวที่โหลดไว้ล่วงหน้า หากไม่มีคำสั่งการติดตาม จะมีเวลาน้อยกว่าหนึ่งวินาที ด้วยบรรทัดการเขียนอาจประมาณ 10 วินาทีโดยมีการเยื้องมากกว่าหนึ่งนาที   -  person Diskdrive    schedule 17.03.2011
comment
เนื่องจากฉันไม่ได้ปรับแต่งคลาส Debug ใด ๆ คุณจึงสามารถสร้างแอปคอนโซลขนาดเล็กที่มีการวนซ้ำและดูประสิทธิภาพที่ลดลงสำหรับตัวคุณเอง   -  person Diskdrive    schedule 17.03.2011
comment
คุณกำลังเรียก Unindent() ในวงหรือไม่? หรือคุณจะสิ้นสุดระดับการเยื้อง 2,000 หลังจากคุณประมวลผล 2,000 แถว   -  person Chansik Im    schedule 17.03.2011


คำตอบ (2)


การดีบัก ใดๆ มีแนวโน้มที่จะทำให้โปรแกรมของคุณช้าลงแม้จะถึงจุดที่ทำงานด้วยความเร็วหนึ่งในสิบก็ตาม มันจะต้องส่งข้อความถึงทั้งผู้ฟังของคุณ (ดูเหมือนว่าคุณไม่มีเลย) และตัวฟังเริ่มต้นซึ่งส่งต่อไปยังทั้ง Debugger.Log และ Win32 OutputDebugString - สงสัยเล็กน้อยว่ามันช้าลงเล็กน้อย :-)

เหตุใดการเยื้องจึงส่งผลกระทบอย่างมาก จริงๆ แล้วคุณไม่ได้เยื้องที่ไหนสักแห่งในวงนั้นหรือไม่? หากคุณไม่ใช่และคุณมี 2,000 รายการ (ตามความคิดเห็นของคุณที่อื่น) นั่นจะมีพื้นที่ค่อนข้างมากที่ด้านหน้าของแต่ละบรรทัดเมื่อคุณเข้าใกล้จุดสิ้นสุด (มีแนวโน้มว่าจะเยื้องเฉลี่ย 1,000 รายการต่อบรรทัด เป็นปัญหา)

person paxdiablo    schedule 17.03.2011
comment
ขอบคุณ! สิ่งที่เยื้องนั้นเป็นอย่างนั้นอย่างแน่นอน - นั่นเป็นเรื่องโง่! - person Diskdrive; 17.03.2011
comment
แม้ว่าฉันอยากจะถามด้วยว่าทำไมการดีบักจึงช้ากว่ามาก หากสิ่งที่ฉันต้องการทำคือสร้างบันทึกที่สามารถจัดการได้ในแอปพลิเคชัน ฉันควรใช้ StringBuilder หรือไม่ มันจะเร็วกว่ามาก ปัญหาเดียวคือฉันไม่สามารถใช้วิธีการเยื้องซึ่งมีประโยชน์ได้ - person Diskdrive; 17.03.2011
comment
การทำบางอย่าง เสมอ ช้ากว่าการไม่ทำอะไรเลย :-) หากคุณต้องการที่จะหมุนของคุณเองจริงๆ ฉันมักจะใส่ if (trace == true) log ("my message"); เพื่อไม่ให้มีการเรียกใช้ฟังก์ชันหากไม่ต้องการการติดตาม มันไม่ใช่วิธี OO แต่หากคุณอยากได้ประสิทธิภาพแบบดิบๆ บางครั้งก็จำเป็น - person paxdiablo; 17.03.2011

ฉันสมมติว่าคุณกำลังเรียก Trace.Indent() สำหรับแต่ละแถวโดยไม่เรียก Trace.Unindent() ซึ่งทำให้ระดับการเยื้องเพิ่มขึ้นอย่างต่อเนื่อง

สมมติว่าคุณมี 2,000 แถวที่ต้องดำเนินการ และคุณกำลังประมวลผลแถวที่ 1,000 ซึ่งทำให้ IndentLevel 1,000 การเยื้องที่คาดไว้จะแสดงด้วยอักขระยูนิโค้ด '\t' (สมมติว่า UTF-16 ซึ่งเท่ากับ 2 ไบต์ต่ออักขระ) จากนั้น เมื่อถึงจุดนั้น ในการสร้างการติดตามการดีบัก จะต้องจัดสรรหน่วยความจำประมาณ 2KB สำหรับการสืบค้นกลับเฉพาะนั้นในการวนซ้ำ การจัดสรรขนาดของหน่วยความจำนั้นไม่ใช่การดำเนินการที่ถูก และคุณกำลังเพิ่มขนาดของรายการการติดตามในการวนซ้ำแต่ละครั้ง

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

คุณอาจต้องการตรวจสอบตัวนับประสิทธิภาพ .NET สำหรับแอปพลิเคชันของคุณ ฉันจะตรวจสอบขนาดของฮีป Gen1, Gen2, Gen3, ขนาดฮีปทั้งหมด, # ของการรวบรวมขยะ Gen1, Gen2, Gen3 ยิ่งแอปพลิเคชันของคุณรวบรวมขยะ Gen มากเท่าใด แอปพลิเคชันของคุณก็จะยิ่งช้าลงเช่นกัน

นี่เป็นเพียงการคาดเดาคร่าวๆของฉัน

person Chansik Im    schedule 17.03.2011