ใช้“ ข้อยกเว้นที่จับได้” เพื่อปรับปรุงความสามารถในการอ่านดีหรือไม่ดี?


9

ในส่วนเวลาที่จะใช้ข้อยกเว้นในThe Pragmatic Programmerหนังสือเขียนว่า:

retcode = OK;
     if (socket.read(name) != OK) {
      retcode = BAD_READ;
    }
     else {
      processName(name);
       if (socket.read(address) != OK) {
        retcode = BAD_READ;
      }
       else {
        processAddress(address);
         if (socket.read(telNo) != OK) {
          retcode = BAD_READ;
        }
         else {
          //  etc, etc...
        }
      }
    }
     return retcode;

พวกเขาชอบ:

 retcode = OK;
     try {
      socket.read(name);
      process(name);
      socket.read(address);
      processAddress(address);
      socket.read(telNo);
      //  etc, etc...
    }
     catch (IOException e) {
      retcode = BAD_READ;
      Logger.log( "Error reading individual: " + e.getMessage());
    }
     return retcode;

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

ฉันสามารถเข้าใจได้ว่าเราควรยกเลิกการเพิ่มประสิทธิภาพจิ๋วสำหรับโค้ด neater (อย่างน้อย 99% ของเวลา) อย่างไรก็ตามจากสิ่งที่ฉันรู้การจับข้อยกเว้นเป็นของคลาสของโค้ด ดังนั้นฉันสงสัยว่าอะไรคือเหตุผลที่ควรใช้โค้ดที่สองมากกว่าโค้ดแรก?

หรือค่อนข้างคุณต้องการรหัสใด


โยกย้ายจากการตรวจสอบรหัสเพราะเป็นคำถามที่ปฏิบัติได้ดีที่สุดไม่ใช่คำถามทบทวนรหัส
Winston Ewert

1
IMO หากคุณคาดว่าจะสามารถอ่าน valuse เหล่านั้นจากซ็อกเก็ตได้แล้ว IOEx นั้นยอดเยี่ยม
Steven Evers


คุณวัดหรือยัง

@ ThorbjørnRavnAndersenแน่นอนว่าฉันกำลังอ่านหนังสือและไม่มี "กรณีทดสอบ" จริง ๆ ในการวัด .. แต่ถ้าเราวัดมันด้วยโค้ดที่มีการประดิษฐ์แล้วแน่นอนว่ามีการลงโทษประสิทธิภาพอยู่แล้ว
Pacerier

คำตอบ:


18

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

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


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

Btw ฉันสงสัยว่าเราจะพิสูจน์ EOFException ที่ DataStreams ใช้ในการตรวจหาจุดสิ้นสุดของบรรทัด (จุดสิ้นสุดของบรรทัดไม่ได้เป็นพิเศษ) ดังที่แสดงในdocs.oracle.com/javase/tutorial/essential/io/datastreams.html ?
Pacerier

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

@ ลงคะแนนเสียงถ้าคุณมีปัญหากับคำตอบโปรดอธิบาย!
Winston Ewert

5

อย่างที่พวกเขาพูดกันว่าข้อยกเว้นควรจัดการกับกรณีพิเศษและเนื่องจากเป็นกรณีพิเศษ (นั่นคือสิ่งที่เกิดขึ้นไม่มากและไกล) ฉันบอกว่าสิ่งนี้ใช้ได้ที่นี่เช่นกัน

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

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


5

ฉันสามารถเข้าใจได้ว่าเราควรยกเลิกการเพิ่มประสิทธิภาพจิ๋วสำหรับโค้ด neater (อย่างน้อย 99% ของเวลา) อย่างไรก็ตามจากสิ่งที่ฉันรู้การจับข้อยกเว้นเป็นของคลาสของโค้ด

คุณรู้ได้จากที่ไหน คุณจะกำหนด "ความล่าช้าที่เห็นได้ชัดเจน" ได้อย่างไร

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

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


ผมมาจาก .NET ดังนั้นการให้อภัยความรู้ของฉันของ Java แต่ผมมีประสบการณ์ส่วนตัวจับข้อยกเว้นใน .NET ก่อให้เกิดความล่าช้าบ้า (ขนาดของวินาที) ซึ่งได้รับการแก้ไขโดยการเอา "จับข้อยกเว้นรหัส" ..
Pacerier

@Pierier อย่างจริงจัง? ขนาดของวินาที? ฉันเดาว่ามันอาจจะเป็นข้อยกเว้นมากมายใช่ไหม จากนั้นฉันก็เห็นได้ว่า
Winston Ewert

3
@Pacerier: หากมีข้อยกเว้นที่ทำให้เกิดความล่าช้าอย่างบ้าคลั่งสิ่งที่ทำให้พวกเขาไม่ได้เป็นพิเศษและดังนั้นจึงควรได้รับการจัดการในรูปแบบอื่น ระบบไม่ควรใช้เวลาในการประมวลผลข้อยกเว้นและฉันคิดว่า Microsoft มีความสามารถเพียงพอที่จะหลีกเลี่ยงปัญหานั้น
David Thornley

5

ฉันเห็นด้วยกับคำตอบที่คุณได้รับแล้วบอกว่านี่เป็นกรณีพิเศษดังนั้นจึงควรใช้การจัดการข้อยกเว้น

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

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

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

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

Bottom line: มีหลายกรณีที่การจัดการข้อยกเว้นค่าโสหุ้ยอาจมีความสำคัญ แต่เกือบจะแน่นอนไม่ใช่หนึ่งในนั้น

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