ไม่ แต่ใช่ แต่อาจจะ แต่อาจเป็นวิธีอื่น แต่ไม่ใช่
ในขณะที่ผู้คนได้ชี้ให้เห็นแล้ว (สมมติว่าภาษาที่มีการเพิ่มความสัมพันธ์ด้านซ้ายเช่น C, C ++, C # หรือ Java) การแสดงออก ((1 + 2) + 3)
1 + 2 + 3
เป็นสิ่งเทียบเท่ากับ พวกเขากำลังเขียนวิธีต่าง ๆ ในซอร์สโค้ดซึ่งจะมีผลกระทบเป็นศูนย์ต่อรหัสเครื่องหรือโค้ดไบต์
ไม่ว่าผลลัพธ์จะเป็นคำสั่งเช่นเพิ่มสองรีจิสเตอร์จากนั้นเพิ่มค่าที่สามหรือนำค่าสองค่าจากสแต็กเพิ่มดันกลับจากนั้นนำค่านั้นมาเพิ่มอีกค่าหรือเพิ่มรีจิสเตอร์สามตัวใน การใช้งานครั้งเดียวหรือวิธีอื่น ๆ ในการหาผลรวมตัวเลขสามตัวขึ้นอยู่กับสิ่งที่เหมาะสมที่สุดในระดับถัดไป (รหัสเครื่องหรือรหัสไบต์) ในกรณีของรหัสไบต์ซึ่งในทางกลับกันจะได้รับโครงสร้างที่คล้ายกันอีกครั้งเช่นค่า IL ที่เท่ากัน (ซึ่งจะเป็นชุดของการโหลดไปยังสแต็กและคู่ popping เพื่อเพิ่มจากนั้นดันผลลัพธ์กลับมา) จะไม่ส่งผลในการคัดลอกโดยตรงของตรรกะนั้นในระดับรหัสเครื่อง แต่สิ่งที่สมเหตุสมผลสำหรับเครื่องที่เป็นปัญหา
แต่มีคำถามของคุณมากกว่านี้
ในกรณีของคอมไพเลอร์ C, C ++, Java หรือ C # ใด ๆ ฉันคาดว่าผลลัพธ์ของคำสั่งทั้งสองที่คุณให้ไว้จะมีผลลัพธ์เหมือนกับ:
int a = 6;
ทำไมรหัสผลลัพธ์เสียเวลาทำคณิตศาสตร์กับตัวอักษร? ไม่มีการเปลี่ยนแปลงสถานะของโปรแกรมที่จะหยุดผลของ1 + 2 + 3
การเป็น6
ดังนั้นนั่นคือสิ่งที่ควรไปในรหัสกำลังดำเนินการ ที่จริงแล้วอาจจะไม่ใช่เช่นนั้น (ขึ้นอยู่กับสิ่งที่คุณทำกับ 6 นั้นบางทีเราสามารถทิ้งทุกอย่างออกไปได้และแม้แต่ C # ด้วยปรัชญาของ "อย่าปรับให้เหมาะสมอย่างหนัก เทียบเท่าint a = 6
หรือเพียงแค่ทิ้งทุกอย่างออกไปโดยไม่จำเป็น)
ถึงแม้ว่าสิ่งนี้จะทำให้เราสามารถขยายคำถามของคุณได้ พิจารณาสิ่งต่อไปนี้:
int a = (b - 2) / 2;
/* or */
int a = (b / 2)--;
และ
int c;
if(d < 100)
c = 0;
else
c = d * 31;
/* or */
int c = d < 100 ? 0 : d * 32 - d
/* or */
int c = d < 100 && d * 32 - d;
/* or */
int c = (d < 100) * (d * 32 - d);
(หมายเหตุตัวอย่างสองตัวอย่างสุดท้ายนี้ไม่ถูกต้อง C # ในขณะที่ทุกอย่างอื่นที่นี่คือและพวกเขาจะถูกต้องใน C, C ++ และ Java.)
ที่นี่อีกครั้งเรามีรหัสเทียบเท่าในแง่ของการส่งออก เนื่องจากไม่ใช่นิพจน์ที่คงที่พวกเขาจะไม่ถูกคำนวณในเวลารวบรวม เป็นไปได้ว่ารูปแบบหนึ่งจะเร็วกว่าอีกรูปแบบหนึ่ง ไหนเร็วกว่ากัน ที่จะขึ้นอยู่กับโปรเซสเซอร์และอาจแตกต่างกันโดยพลการในบางรัฐ (โดยเฉพาะอย่างยิ่งถ้าหากเร็วกว่าก็ไม่น่าจะเร็วขึ้นมาก)
และพวกเขาไม่ได้เกี่ยวข้องกับคำถามของคุณอย่างสิ้นเชิงเนื่องจากพวกเขาส่วนใหญ่เกี่ยวกับความแตกต่างในลำดับที่บางสิ่งบางอย่างจะทำแนวคิด
ในแต่ละของพวกเขามีเหตุผลที่สงสัยว่าอาจจะเร็วกว่าคนอื่น decrements โสดอาจจะมีการเรียนการสอนเฉพาะดังนั้นแน่นอนอาจจะเร็วกว่า(b / 2)--
บางทีอาจจะสามารถผลิตได้เร็วขึ้นโดยการเปลี่ยนมันเป็นเช่นนั้นทำให้เร็วกว่า(b - 2) / 2
d * 32
d << 5
d * 32 - d
d * 31
เร็วกว่าความแตกต่างระหว่างสองสิ่งสุดท้ายนั้นน่าสนใจเป็นพิเศษ อนุญาตให้มีการประมวลผลบางอย่างที่จะข้ามในบางกรณี แต่อื่น ๆ หลีกเลี่ยงความเป็นไปได้ของการคาดการณ์ผิดพลาดสาขา
ดังนั้นนี่ทำให้เรามีคำถามสองข้อ: 1. จริง ๆ แล้วเร็วกว่าอีกคำถามหนึ่ง? 2. คอมไพเลอร์จะแปลงช้ากว่าให้เร็วขึ้นหรือไม่
และคำตอบคือ 1 มันขึ้นอยู่กับ 2. อาจจะ
หรือเพื่อขยายมันขึ้นอยู่กับว่ามันขึ้นอยู่กับหน่วยประมวลผลที่มีปัญหา แน่นอนว่ามีโปรเซสเซอร์ที่มีอยู่ซึ่งรหัสเครื่องที่ไร้เดียงสาของหนึ่งจะเร็วกว่าตัวเทียบรหัสเครื่องอื่น ๆ ในช่วงเวลาแห่งประวัติศาสตร์ของการคำนวณทางอิเล็กทรอนิกส์ไม่มีสิ่งใดที่เร็วกว่าเสมอเช่นกัน (องค์ประกอบการคาดคะเนความผิดพลาดของสาขาโดยเฉพาะนั้นไม่เกี่ยวข้องกับหลาย ๆ อย่างเมื่อซีพียูที่ไม่ได้ถูกวางท่อเป็นเรื่องปกติมากขึ้น)
และอาจเนื่องจากมีหลาย optimisations ที่ compilers (และ jitters และ script-engine) จะทำและในขณะที่บางคนอาจได้รับคำสั่งในบางกรณีเราโดยทั่วไปจะสามารถหารหัสเทียบเท่าที่มีเหตุผลบางอย่างที่ แม้แต่คอมไพเลอร์ที่ไร้เดียงสาที่สุดก็มีผลลัพธ์เหมือนกันและบางส่วนของโค้ดที่มีเหตุผลเทียบเท่าซึ่งแม้แต่โค้ดที่ซับซ้อนที่สุดก็ยังสร้างโค้ดที่เร็วกว่าสำหรับอีกอันหนึ่งสำหรับอีกอันหนึ่ง (แม้ว่าเราจะต้องเขียนบางอย่างทางพยาธิวิทยาทั้งหมด
ดูเหมือนว่าจะเป็นข้อกังวลในการเพิ่มประสิทธิภาพขนาดเล็กมาก
ไม่แม้แต่กับความแตกต่างที่ซับซ้อนกว่าที่ฉันให้ไว้ที่นี่ดูเหมือนว่าจะเป็นข้อกังวลเล็กน้อยที่ไม่เกี่ยวข้องกับการปรับให้เหมาะสม ถ้ามีอะไรที่มันเป็นเรื่องของ pessimisation ตั้งแต่คุณสงสัยว่ายากที่จะอ่านอาจจะช้ากว่าให้อ่านง่ายขึ้น((1 + 2) + 3
1 + 2 + 3
แต่การเลือก C ++ มากกว่า C # / Java / ... นั้นเป็นเรื่องของการปรับให้เหมาะสมที่สุด (IMHO)
ถ้านั่นคือสิ่งที่เลือก C ++ มากกว่า C # หรือ Java คือ "all about" ฉันบอกว่าคนควรจะเขียนสำเนาของ Stroustrup และ ISO / IEC 14882 และเพิ่มพื้นที่ว่างของคอมไพเลอร์ C ++ เพื่อให้มีที่ว่างสำหรับ MP3 หรืออะไรมากกว่านั้น
ภาษาเหล่านี้มีข้อดีที่แตกต่างกัน
หนึ่งในนั้นคือ C ++ โดยทั่วไปจะยังเร็วกว่าและเบากว่าเมื่อใช้หน่วยความจำ ใช่มีตัวอย่างที่ C # และ / หรือ Java เร็วขึ้นและ / หรือมีการใช้หน่วยความจำตลอดอายุการใช้งานของแอปพลิเคชันที่ดีขึ้นและสิ่งเหล่านี้เป็นเรื่องธรรมดามากขึ้นเมื่อเทคโนโลยีที่เกี่ยวข้องปรับปรุง แต่เรายังคาดหวังว่า executable ขนาดเล็กที่ทำงานได้เร็วขึ้นและใช้หน่วยความจำน้อยกว่าเทียบเท่าในภาษาใดภาษาหนึ่ง
นี่ไม่ใช่การเพิ่มประสิทธิภาพ
การเพิ่มประสิทธิภาพบางครั้งใช้เพื่อหมายถึง "ทำให้ทุกอย่างเป็นไปได้เร็วขึ้น" เป็นเรื่องที่เข้าใจได้บ่อยครั้งเมื่อเราพูดถึง "การเพิ่มประสิทธิภาพ" เรากำลังพูดถึงการทำให้สิ่งต่าง ๆ เป็นไปอย่างรวดเร็วยิ่งขึ้นดังนั้นคน ๆ หนึ่งจึงกลายเป็นคนอื่นและฉันจะยอมรับว่าฉันใช้คำนั้นในทางที่ผิด
คำที่ถูกต้องสำหรับ "การทำสิ่งที่ไปได้เร็วขึ้น" ไม่ได้เพิ่มประสิทธิภาพ คำที่ถูกต้องที่นี่คือการปรับปรุง หากคุณทำการเปลี่ยนแปลงโปรแกรมและความแตกต่างที่มีความหมายเพียงอย่างเดียวคือตอนนี้มันเร็วขึ้นแล้วมันไม่ได้ถูกปรับให้เหมาะสม แต่อย่างใดดีกว่า
การเพิ่มประสิทธิภาพคือเมื่อเราทำการปรับปรุงในแง่มุมหนึ่งและ / หรือกรณีเฉพาะ ตัวอย่างทั่วไปคือ:
- ตอนนี้มันเร็วกว่าสำหรับเคสที่ใช้เพียงเคสเดียว แต่จะช้ากว่าสำหรับเคสอื่น
- ตอนนี้เร็วขึ้น แต่ใช้หน่วยความจำมากขึ้น
- ตอนนี้มันเบาลงในหน่วยความจำ แต่ช้ากว่า
- ตอนนี้เร็วขึ้น แต่ยากที่จะรักษา
- ตอนนี้มันง่ายต่อการบำรุงรักษา แต่ช้าลง
กรณีดังกล่าวจะมีเหตุผลหากเช่น:
- กรณีการใช้งานที่เร็วขึ้นนั้นพบได้บ่อยหรือมีอุปสรรคมากขึ้นในการเริ่มต้น
- โปรแกรมช้าและไม่ได้รับการยอมรับและเรามี RAM จำนวนมากฟรี
- โปรแกรมกำลังหยุดทำงานเนื่องจากใช้ RAM จำนวนมากจึงใช้เวลาในการแลกเปลี่ยนมากกว่าการประมวลผลเร็วสุด
- โปรแกรมช้าอย่างไม่อาจยอมรับได้และรหัสที่ยากต่อการทำความเข้าใจนั้นเป็นเอกสารที่ดีและค่อนข้างเสถียร
- โปรแกรมยังคงยอมรับได้อย่างรวดเร็วและยิ่งรหัสฐานที่เข้าใจได้ถูกกว่าเพื่อรักษาและช่วยให้การปรับปรุงอื่น ๆ ทำได้ง่ายขึ้น
แต่กรณีดังกล่าวจะไม่ได้รับการพิสูจน์ในสถานการณ์อื่น ๆ : รหัสไม่ได้รับการปรับปรุงให้ดีขึ้นโดยการวัดคุณภาพที่ไม่ผิดพลาดอย่างแน่นอน แต่ก็ดีขึ้นกว่าเดิมในเรื่องใดเรื่องหนึ่งที่เหมาะสมกว่าสำหรับการใช้งานเฉพาะด้าน การเพิ่มประสิทธิภาพ
และการเลือกภาษามีผลกระทบที่นี่เพราะความเร็วการใช้หน่วยความจำและความสามารถในการอ่านสามารถได้รับผลกระทบจากมัน แต่สามารถเข้ากันได้กับระบบอื่น ๆ ความพร้อมใช้งานของไลบรารีความพร้อมใช้งานของรันไทม์ (เพราะบาปของฉันฉันลงเอยด้วยการใช้ Linux และ Android เป็นระบบปฏิบัติการที่ฉันโปรดปรานและ C # เป็นภาษาที่ฉันชอบและในขณะที่ Mono ยอดเยี่ยม แต่ฉันก็ยังเจอกับเรื่องนี้ไม่มาก)
การพูดว่า "การเลือก C ++ เหนือ C # / Java / ... เป็นเรื่องเกี่ยวกับการปรับให้เหมาะสมที่สุด" จะสมเหตุสมผลถ้าคุณคิดว่า C ++ แย่มากเพราะการเพิ่มประสิทธิภาพนั้นเกี่ยวกับ "ดีกว่าแม้จะ ... " ไม่ "ดีกว่า" หากคุณคิดว่า C ++ นั้นดีกว่าตัวมันเองสิ่งสุดท้ายที่คุณต้องทำคือต้องกังวลเกี่ยวกับ micro-opts ที่เป็นไปได้ แน่นอนคุณน่าจะดีกว่าที่จะละทิ้งมันไปเลย แฮ็กเกอร์ที่มีความสุขคือคุณภาพที่จะเพิ่มประสิทธิภาพด้วยเช่นกัน!
หากคุณมีแนวโน้มที่จะพูดว่า "ฉันรัก C ++ และสิ่งหนึ่งที่ฉันชอบเกี่ยวกับมันคือการบีบรอบพิเศษ" นั่นก็เป็นอีกเรื่องหนึ่ง มันยังคงเป็นกรณีที่ micro-opts นั้นคุ้มค่าหากพวกเขาสามารถเป็นนิสัยที่สะท้อนกลับได้ (นั่นคือวิธีที่คุณมักจะเขียนโค้ดตามธรรมชาติจะเร็วกว่าที่ช้ากว่า) มิฉะนั้นพวกเขาไม่ได้เพิ่มประสิทธิภาพการคลอดก่อนกำหนดพวกเขากำลังมองในแง่ร้ายก่อนกำหนดที่จะทำให้สิ่งเลวร้ายลง