งานที่ผมทำอยู่ (ยังไม่เสร็จ) code ของ app จริง ๆ ตอนนี้แค่ 3 พันกว่าบรรทัด แต่มีใช้ template haskell กับ quasiquotation หลายที่ + lens นิดหน่อย compile ทั้ง project ล่อไป 1 นาที ถ้าไปแก้ module ที่ module อื่นมายุ่งแล้ว compile ใหม่ ก็รอไปครึ่งนาที ไม่รู้มันช้าเอง เครื่องห่วย หรือผมเขียนอะไร noob ๆ ทำให้ compiler มันงงก็ไม่รู้
แต่จะนั่งขุดรายละเอียด GHC หาทางเอาใจ compiler ก็คงไม่ไหว.. เลยลอง google แล้วก็เจอคนเขียนเรื่องนี้ไว้พอดี เค้าลองปรับ options ต่าง ๆ ของ GHC แล้วเอามาเทียบกันให้เราดู ว่าทำอะไรแล้วมันเร็วขึ้นแค่ไหน https://rybczak.net/2016/03/26/how-to-reduce-compilation-times-of-haskell-projects/
สำหรับใครขี้เกียจอ่าน ขอคำตอบแบบ stackoverflow:
- ปิด optimizer (-O0) นอกจากเรื่อง correctness แล้ว GHC ยังใช้เวลาไม่น้อยไป optimize code อย่างหนักหน่วง เพื่อให้ code เราให้ทำงานได้เร็ว แต่เวลาเรา develop เราไม่ได้ต้องการเร็วอะไรขนาดนั้น ขอแค่เช็คว่า type ถูกมั้ย test พอได้ก็พอ ดังนั้นก็ปิด optimizer มันซะ
- เพิ่ม heap (+RTS -A128m -n2m -RTS) เพราะ GHC เสียเวลาไปกับ garbage collection (GC) ตอน compile เยอะมาก ประมาณ 25 วิ จาก 65 ถ้าเพิ่ม heap ให้เยอะ ๆ GC ก็จะวิ่งน้อยลง เป็นการแลก memory กับ time
- parallel compilation (-j) ใส่แล้ว GHC จะหาเองว่า module ไหนไม่มี dependency ก็จะ compile พร้อม ๆ กันไปเลย
ผลคือเร็วขึ้น เยอะมาก จาก 65 วิ เหลือแค่ 23 วิ... สบายละ
ปล: ใครคิดว่าเขียน haskell แล้ววงจร code feedback มันจะช้า จะขาดตอน ใจเย็น ๆ อย่าตื่นตูม แค่ลง intero (http://commercialhaskell.github.io/intero/) ตอนนี้มีแต่เป็น emacs plugin คุณก็จะได้ editor ที่ขีดเส้นตัวแดง ๆ ตรงที่ code ผิด เราเอา cursor ไปแหย่ก็รู้ทันทีว่าต้องแก้เพราะอะไร โดยไม่ต้อง compile ใหม่แม้แต่ตัวเดียว โค้ดทั่วไปรอประมาณครึ่งวิ โค้ดหนืด ๆ อย่าง template haskell รอไม่เกิน 3 วิ หรือจะลอง test บาง function ก็มี repl ให้ใช้ใน emacs ที่ intero มันเร็วเพราะหลังบ้านมันใช้ GHCi ในการ interpret code เรา ก็เลยเร็วเหมือนภาษา dynamic แต่เป๊ะ เหมือนวิ่งผ่าน compiler
No comments:
Post a Comment