รวบรวมสิ่งที่ผ่านมานานไหม?


38

มีเรื่องราวสงครามนับไม่ถ้วนเกี่ยวกับระยะเวลาในการคอมไพล์ แม้แต่xkcdก็พูดถึงมัน

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

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


31
ลองรวบรวมโครเมียม
UldisK

2
หยิบสำเนาของเคอร์เนล linux ทำโครงสร้างที่สมบูรณ์ ดูด้วยตัวคุณเอง หรือสปริงจากแหล่งหากคุณเป็น Java coder ตามที่เป็นอยู่คำถามนี้มีหลายคำตอบที่ตอบคำถามราวกับว่าเป็นแบบสำรวจความคิดเห็น ("ฉันได้รวบรวม 30 นาที ... " พิมพ์คำตอบ) ซึ่งเป็นข้อบ่งชี้ว่าคำถามนั้นไม่เหมาะสม .

โครงการขนาดใหญ่เมื่อเร็ว ๆ นี้ใช้เวลารวบรวม 40 นาที (ซอร์สโค้ดไฟล์ 40,000 ไฟล์รวบรวมกับ Maven) วิธีแก้ปัญหาคือการคอมไพล์การรวบรวมบนคอร์ CPU หลายตัว
Niklas Rosencrantz

2
เลือกแหล่งจำหน่าย Linux (gentoo, LFS, ... ) จากนั้นใช้เวลาหลายวันในการรวบรวมซอฟต์แวร์ทุกตัวที่คุณติดตั้ง
Basile Starynkevitch

6
คำนิยามยาว ... สำหรับเด็กบางคนที่เพิ่งออกจากโรงเรียน 1 นาทีอาจดูยาวไปสำหรับคนอายุเก่าที่อยู่ในสนามเพลาะมานานหลายทศวรรษสองสามชั่วโมงไม่ยกคิ้ว
jwenting

คำตอบ:


48

การรวบรวมอาจใช้เวลาสักครู่โดยเฉพาะอย่างยิ่งสำหรับโครงการขนาดใหญ่ที่เขียนในภาษาเช่น C, C ++ หรือ Scala การคอมไพล์ส่วนต่าง ๆ ในพื้นหลังสามารถลดเวลาการคอมไพล์ แต่บางครั้งคุณต้องทำการคอมไพล์ใหม่ ปัจจัยที่สามารถนำไปสู่การรวบรวมครั้งที่ยาวนาน ได้แก่ :

  • ขนาดรหัสใหญ่ชัด โครงการขนาดใหญ่จะมีโค้ดนับแสนบรรทัด

  • #includeคำสั่งพรีโปรเซสเซอร์ของ C ซึ่งทำให้โค้ดเดียวกันนั้นสามารถรวบรวมได้หลายร้อยครั้ง ระบบมาโครมีปัญหาที่คล้ายกันเนื่องจากทำงานในระดับข้อความ ตัวประมวลผลล่วงหน้าขยายขนาดโค้ดที่ส่งไปยังคอมไพเลอร์จริงๆ การดูไฟล์หลังจากการประมวลผลล่วงหน้า (เช่นผ่านgcc -E) ควรเปิดตาของคุณ

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

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

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


14
ที่จริงแล้วระบบพิมพ์ของ Scala นั้นสมบูรณ์แบบทัวริงดังนั้นการตรวจสอบประเภทจึงใช้เวลาไม่ จำกัด และเป็นไปไม่ได้ที่คอมไพเลอร์จะพิจารณาว่า
Jörg W Mittag

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

ฉันยอมรับคำตอบนี้เพราะคุณชี้ให้เห็นหลายสิ่งที่ฉันไม่ได้พิจารณาโดยเฉพาะการรวบรวมสิ่งทั้งหมดกับการรวบรวมเป็นชิ้น ๆ และความจริงที่ว่าชุดทดสอบอาจรวมอยู่ใน "การรวบรวม" ในเวลานี้
Thunderforge

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

1
คำตอบที่ดีฉันเพิ่งจะทราบว่าการแพร่กระจายของเวลารวบรวมที่เป็นไปได้มีขนาดใหญ่กว่ามาก ฉันได้ทำงานในโครงการที่การรวบรวมเต็มอาจใช้เวลาสองถึงสามวัน (ใช่ที่น่ากลัว!) และฉันคิดว่ามีผู้กระทำผิดที่เลวร้ายยิ่งขึ้นมี
รอยต.

17

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

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


1
javac ไม่ได้ " ข้ามการรวบรวมล่วงหน้าและการเชื่อมโยงค่าใช้จ่ายทั้งหมด " มันข้ามค่าใช้จ่ายในการเพิ่มประสิทธิภาพจำนวนมาก แต่ก็ยังคงเปลี่ยนแหล่งข้อมูลเป็นไบต์และทำการตรวจสอบแบบคงที่จำนวนมากในกระบวนการ มันเกี่ยวกับการเชื่อมโยงมากพอ ๆ กับคอมไพเลอร์ C ความแตกต่างด้านประสิทธิภาพที่แท้จริงคือกระบวนการรวบรวมของ Java ได้รับการออกแบบในยุคที่มีความเป็นไปได้ที่จะโหลดโปรแกรมทั้งหมดและการพึ่งพาลงในหน่วยความจำในครั้งเดียวแทนที่จะต้องแบ่งมันออกเป็นชิ้นเล็ก ๆ
Peter Taylor

10

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

อย่างไรก็ตามมีกระบวนการคล้ายการคอมไพล์อื่น ๆ ซึ่งอาจใช้เวลานานกว่านั้น การออกแบบวงจรดิจิตอล (สำหรับ ASICs หรือ FPGAs) ต้องใช้สถานที่และขั้นตอนเส้นทาง ขั้นตอนสถานที่และเส้นทางเป็นที่ตั้งของแต่ละประตูตรรกะ flip-flop ลงทะเบียน RAM และส่วนประกอบอื่น ๆ จะถูกกำหนดพร้อมกับเส้นทางสำหรับการเดินสายเชื่อมต่อระหว่างกัน ซอฟต์แวร์ใช้ตัวแบบเวลาเพื่อกำหนดเกตและความล่าช้าในการกำหนดเส้นทางสำหรับตำแหน่งที่เป็นไปได้เปรียบเทียบสิ่งเหล่านี้กับข้อ จำกัด ที่กำหนดโดยข้อ จำกัด ด้านเวลาจากนั้นปรับตำแหน่งการวางและเส้นทางลวดเพื่อลองรับความต้องการด้านเวลา บางครั้งซอฟต์แวร์จะต้องปรับขนาดประตูและเพิ่มบัฟเฟอร์เพื่อให้ตรงตามเวลา ขั้นตอนนี้เข้มข้นอย่างยิ่งในการคำนวณและอาจใช้เวลาหลายชั่วโมงหรือหลายวันกว่าจะเสร็จสมบูรณ์ มันยังไม่ค่อยขนานกันดีมาก มีการออกแบบ FPGA ที่ฉันทำงานเมื่อประมาณหนึ่งปีที่แล้วซึ่งใช้เวลาประมาณครึ่งหนึ่งของ Virtex 6 HXT 565 FPGA (~ 300k จาก 565k LUTs) และใช้เวลาประมาณ 7 ชั่วโมงเพื่อทำสถานที่และเส้นทางให้เสร็จ ฉันไม่สามารถจินตนาการได้ว่าจะต้องใช้เวลานานแค่ไหนในการวิ่งและวิ่งบนเส้นทางบางอย่างเช่นการออกแบบซีพียู Core i7 - อาจอย่างน้อยก็หลายสัปดาห์


4

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

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

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


3

เล็กน้อยทั้งคู่ C ++ (และ C ในระดับที่น้อยกว่า) มีชื่อเสียงในเรื่องเวลาการรวบรวมที่ช้าโดยเฉพาะในช่วงเวลาของฮาร์ดแวร์ ในช่วงเปลี่ยนสหัสวรรษฉันทำงานในโครงการที่ใช้เวลาประมาณ 4 ชั่วโมงในการสร้างเนื่องจากคนมาโครชาวมณฑล

ทุกวันนี้สิ่งต่าง ๆ ดีขึ้น แต่ 30 วินาทีนั้นค่อนข้างต่ำในประสบการณ์ของฉัน - โดยเฉพาะอย่างยิ่งในงานสร้างที่จำเป็นต้องตรวจสอบสิ่งต่าง ๆ จากแหล่งควบคุมการทดสอบหน่วยรันตัวติดตั้งและทุกสิ่งที่ส่งไปยัง SAN บางแห่ง


2

ขึ้นอยู่กับโครงการและสภาพแวดล้อมที่รวบรวม ฉันทำงานในโครงการ C ++ ซึ่งใช้เวลาหลายนาทีในการรวบรวม (ตั้งค่าเป็นหลายโครงการใน MSVS) ซึ่งอาจเป็นเวลาที่เพียงพอสำหรับการสู้ฟันดาบ

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

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