Compiling and targets
Codegen targets#
Faber มีภาษาเดียวและมีสัญญาการคอมไพล์หลายรูปแบบ ฟีเจอร์แต่ละอย่างไม่จำเป็นต้องลดรูปไปยังทุกเป้าหมายได้ หน้านี้อธิบายว่าแต่ละเป้าหมายรองรับ ลบออก แจ้งเตือน หรือปฏิเสธฟีเจอร์ใดบ้าง
คำกริยาตามนโยบาย#
| คำกริยา | ความหมาย |
|---|---|
| รองรับ | ลดรูปด้วยความหมายตามที่กำหนด |
| ลบออก | ตรวจสอบชนิดข้อมูลได้ แต่การสร้างโค้ดจะละทิ้งความหมายเฉพาะของเป้าหมาย |
| เตือน | เป็น Faber ที่ถูกต้องตามกฎหมาย แต่ไม่มีผลหรือมีพฤติกรรมลดทอนบนเป้าหมาย |
| ปฏิเสธ | การตรวจสอบหรือการส่งออกล้มเหลวพร้อมข้อความวินิจฉัยที่ชัดเจน |
| เลื่อนดำเนินการ | แยกวิเคราะห์และผูกชื่อได้ แต่ยังไม่ได้ทำการลดรูปสำหรับเป้าหมายใด |
| จำกัด | สัญญาที่เสถียรพร้อมเงื่อนไขขอบเขตย่อยที่ชัดเจน |
ตารางเป้าหมาย#
| เป้าหมาย | เลน | สร้าง | รัน | แพ็กเกจ | นโยบาย |
|---|---|---|---|---|---|
rust | HIR | ใช่ | ใช่ | ใช่ | รองรับ |
fmir-text | MIR | ใช่ | ใช่ | ใช่ | รองรับ |
fmir | MIR | ใช่ | ใช่ | ใช่ | รองรับ |
fmir-bin | MIR | ใช่ | ใช่ | ใช่ | รองรับ |
faber | HIR | ใช่ | ไม่ | ไม่ | รองรับ |
ts | HIR | ใช่ | ไม่ | ไม่ | ตรวจสอบ |
go | HIR | ใช่ | ไม่ | ไม่ | ลบออก |
wasm | MIR | ใช่ | ไม่ | ไม่ | จำกัด |
wasm-text | MIR | ใช่ | ไม่ | ไม่ | จำกัด |
llvm-text | MIR | ใช่ | ไม่ | ไม่ | จำกัด |
metal-text | MIR | ใช่ | ไม่ | ไม่ | จำกัด |
wgsl-text | MIR | ใช่ | ไม่ | ไม่ | จำกัด |
sexp | MIR | ใช่ | ไม่ | ไม่ | จำกัด |
การกำหนดเส้นทางไปป์ไลน์#
Source → Lex → Parse → Collect → Resolve → Lower → Typecheck → Analysis
↓
┌─────────────────────────┴──────────┐
│ │
HIR backends MIR backends
│ │
Rust · Faber · TS · Go fmir · wasm · llvm · metal · wgsl · sexpเลนแอปพลิเคชัน (HIR)#
| เป้าหมาย | ระดับพื้นฐานที่วัดได้ |
|---|---|
| Rust | เส้นทางสำหรับใช้งานจริง รองรับโหมดยืม การสร้าง CLI และการลดรูป Result ที่อาจล้มเหลว |
| Faber | มุมมองซอร์สตามรูปแบบมาตรฐาน / การแปลงไปกลับ ไม่ใช่แบ็กเอนด์สำหรับการประมวลผล |
| TypeScript | วิเคราะห์แล้ว 288/318 รายการ · ตรวจสอบชนิดข้อมูลผ่าน 268/318 รายการ · รันได้ 262/318 รายการ |
| Go | ผ่าน 146/216 รายการ โหมดยืมถูกลบออก และ ad ถูกปฏิเสธ |
เลนระบบ (MIR)#
| เป้าหมาย | ระดับพื้นฐานที่วัดได้ |
|---|---|
| fmir* | อิมเมจ MIR ของแพ็กเกจ ตัวรันพิสูจน์ว่าไม่ขึ้นกับซอร์ส |
| wasm | ส่งออกแล้ว 200/289 รายการ · ตรวจสอบความถูกต้องผ่าน 195/289 รายการ · รันด้วย stub host ได้ 171/289 รายการ |
| llvm-text | ส่งออกแล้ว 249/289 รายการ · ผ่านการตรวจสอบ 232/289 รายการ · รันได้ 65/289 รายการ |
| metal-text | ชุดย่อยของเคอร์เนลที่ปลอดภัยสำหรับอุปกรณ์ มีการทดสอบเฉพาะจุด 88 รายการ แคมเปญหยุดชั่วคราว |
| wgsl-text | ตรวจสอบด้วย naga 30.x มีการทดสอบเฉพาะจุด 87 รายการ และมี sidecar สำหรับการสะท้อนข้อมูล |
| sexp | ส่งออกแล้ว 193 รายการ · คอมไพล์ด้วย Racket แล้ว 190 รายการ · รันด้วย Racket แล้ว 190 รายการ เป้าหมายสำหรับการตรวจสอบความถูกต้อง |
สำหรับแฟล็กความสามารถล่าสุด ให้รัน faber targets
Compilation lanes#
Faber มีฟรอนต์เอนด์ร่วมเพียงชุดเดียว ได้แก่ การวิเคราะห์คำศัพท์ การแยกวิเคราะห์ และการตรวจสอบชนิด จากนั้นจึงแยกไปยังเส้นทางการลดรูปหลายรูปแบบตามความต้องการของเป้าหมาย ตัวแทนระดับกลางก่อตัวเป็นไปป์ไลน์: ซอร์สโค้ดถูกวิเคราะห์เป็น HIR จากนั้นอาจลดรูปเป็น MIR และอาจแวะผ่าน AIR ก่อนส่งออกขั้นสุดท้าย IR แต่ละแบบมีหน้าที่เฉพาะ และแต่ละเป้าหมายจะรับอินพุตจาก IR ที่เหมาะกับความต้องการของตน
ภาพรวมไปป์ไลน์#
Source (.fab) → Lex → Parse → Collect → Resolve → Lower → Typecheck → Analysis
│
HIR (semantic core)
┌─────┴─────┐
│ │
Reader locale MIR lowering
(input/output) │
│
┌─────────┴─────────┐
│ │
CPU lanes GPU lanes
│ │
┌────┬────┼────┬────┐ ┌───┴───┐
│ │ │ │ │ │ │
FMIR LLVM WASM TS Go WGSL Metal
(hold)ฟรอนต์เอนด์ชุดเดียวกันนี้ให้บริการทุกเป้าหมาย หลังจากการวิเคราะห์เชิงความหมายสร้าง HIR แล้ว คอมไพเลอร์จะเลือกเส้นทางตามเป้าหมาย:
- HIR-direct — ส่งออกโดยตรงจาก HIR ที่ตรวจสอบชนิดแล้ว สำหรับแบ็กเอนด์ที่มีรูปแบบใกล้เคียงภาษา (Rust, Faber, TypeScript, Go)
- HIR → MIR — ลดรูปเป็น MIR ที่มีรูปแบบใกล้เคียงการทำงาน จากนั้นจึงส่งออกสำหรับเป้าหมายระบบและเป้าหมายระดับล่าง
- HIR → MIR → AIR → MIR — แวะผ่าน AIR แบบฟังก์ชันบริสุทธิ์สำหรับการแปลงออโตดิฟและฟิวชัน จากนั้นจึงกลับเข้าสู่ MIR
HIR — ตัวแทนระดับกลางระดับสูง#
HIR คือแหล่งความจริง เป็น IR ที่มีชนิดและมีรูปแบบใกล้เคียงภาษา ซึ่งยังคงรักษาการประกาศ ข้อมูลชนิด และความสัมพันธ์เชิงโครงสร้างไว้ ทุกโปรแกรม Faber ไม่ว่าจะมาจากโลแคลเดิมหรือมีปลายทางเป็นเป้าหมายใด ล้วนต้องผ่านตัวแทนนี้
การผสานรวมกับโลแคลผู้อ่าน#
โลแคลผู้อ่านทำงานผ่าน HIR ไฟล์ซอร์ส Faber ที่เขียนด้วยคีย์เวิร์ดภาษาไทยจะถูกแยกวิเคราะห์และลดรูปเป็น HIR เดียวกับซอร์สที่เทียบเท่ากันในภาษาละติน โลแคลเป็นการแสดงผลระดับพื้นผิวของ HIR ไม่ใช่การแยกแขนงในแกนเชิงความหมาย
- อินพุต: ซอร์สที่แปลเป็นภาษาท้องถิ่น (ไทย จีน อาหรับ และอื่น ๆ) → HIR ที่ทำให้เป็นมาตรฐานแล้ว — ใช้งานแล้ว
- เอาต์พุต: HIR → การส่งออกซอร์สที่แปลเป็นภาษาท้องถิ่นอีกครั้ง — อยู่ระหว่างดำเนินการ (กำลังพัฒนา)
เมื่อทิศทางเอาต์พุตพร้อมใช้งาน faber format --reader-locale=th-TH จะวนรอบซอร์ส Faber ใด ๆ ผ่าน HIR และส่งออกด้วยคีย์เวิร์ดภาษาไทย ทำให้ความสมมาตรเสร็จสมบูรณ์: HIR เดียวกันสามารถสร้างพื้นผิวของโลแคลใด ๆ ได้ เช่นเดียวกับที่สามารถสร้างเอาต์พุตสำหรับแบ็กเอนด์เป้าหมายใด ๆ
แบ็กเอนด์ HIR-direct#
เป้าหมายเหล่านี้ส่งออกโดยตรงจาก HIR ที่ตรวจสอบชนิดแล้ว โดยไม่ลดรูปเป็น MIR จึงรักษาโครงสร้างระดับซอร์สไว้ได้นานกว่า และเหมาะกับเอาต์พุตที่มีรูปแบบใกล้เคียงภาษา:
| เป้าหมาย | สถานะ | บทบาท |
|---|---|---|
Rust | หลัก | เส้นทางสำหรับการใช้งานจริง แพ็กเกจ การบิลด์ การรัน และการทดสอบ ใช้ Cargo + rustc สำหรับไบนารีเนทีฟ |
Faber | รองรับ | มุมมองซอร์สตามรูปแบบมาตรฐานผ่านฟอร์แมตเตอร์ forma พร้อมความเสถียรในการวนรอบ |
TypeScript | ตรวจสอบ | ส่งออกไฟล์เท่านั้น ใช้พิสูจน์ความหมายข้ามรูปแบบเป้าหมาย |
Go | ลบรูป | ส่งออกไฟล์เท่านั้น โหมดการยืมจะถูกลบออก และปฏิเสธ ad |
MIR — ตัวแทนระดับกลางระดับกลาง#
MIR คือ IR ที่มีรูปแบบใกล้เคียงการทำงาน โดยแสดงโฟลว์การควบคุม ตัวแปรโลคัล การเรียกใช้รันไทม์ ตำแหน่ง สาขา และขอบเขตข้อผิดพลาด ซึ่งเป็นข้อเท็จจริงที่เป้าหมายระดับล่างต้องใช้ ขณะที่ HIR รักษาโครงสร้างของซอร์ส MIR จะทำให้โครงสร้างนั้นแบนลงเป็นกราฟโฟลว์การควบคุม
การลดรูป HIR → MIR จะแปลงโครงสร้างที่มีรูปแบบใกล้เคียงภาษาให้เป็นขั้นตอนการทำงาน MIR จะถูกตรวจสอบหลังการลดรูป เพื่อดักจับปัญหาเชิงโครงสร้างก่อนที่แบ็กเอนด์ใด ๆ จะพยายามส่งออก
ความเป็นเจ้าของเชิงความหมาย Faber รักษาขอบเขตที่ชัดเจนระหว่างกฎที่บังคับใช้ใน HIR/MIR (การตรวจสอบชนิด การกำหนดค่าอย่างแน่นอน และลินต์โหมดการยืม) กับกฎที่ปล่อยให้ชุดเครื่องมือของเป้าหมายจัดการ (การวิเคราะห์อายุการใช้งานของ Rust และความปลอดภัยด้านชนิดของ Go) วิธีนี้ป้องกันไม่ให้คอมไพเลอร์ทำงานซ้ำกับสิ่งที่คอมไพเลอร์ของเป้าหมายทำได้ถูกต้องอยู่แล้ว
การแวะผ่าน AIR#
AIR (Autograd / AI Representation) คือเส้นทางแวะผ่านสำหรับการแปลงแบบฟังก์ชันบริสุทธิ์ ซึ่งแยกออกจากเส้นทาง HIR → MIR การเข้าสู่เส้นทางนี้เกิดจากคำอธิบายประกอบที่ระบุอย่างชัดเจนบนฟังก์ชันแต่ละรายการ:
@ radix lane "air"
functio loss(numerus predicted, numerus expected) → numerus {
fixum numerus delta ← predicted - expected
redde delta * delta
}ฟังก์ชันในเลน AIR ต้องเป็นไปตามนโยบายความบริสุทธิ์ — ห้ามมีการกลายสภาพ ห้ามมีเอฟเฟกต์ และห้ามมีลูป ฟังก์ชันที่ละเมิดเงื่อนไขนี้จะถูกปฏิเสธพร้อมข้อความวินิจฉัยก่อนเริ่มการลดรูปเป็น AIR ส่วนที่เหลือของโปรแกรมยังคงใช้ Faber ตามปกติ ซึ่งรองรับการกลายสภาพ เอฟเฟกต์ และลูป
หลังจากการแปลง AIR ทำงานเสร็จ (ในอนาคตจะรองรับออโตดิฟและฟิวชัน) ผลลัพธ์จะถูกลดรูปกลับเป็น MIR และกลับเข้าสู่ไปป์ไลน์แบ็กเอนด์ MIR ตามปกติ AIR ไม่มีแบ็กเอนด์ของตนเองและไม่มีตัวตรวจสอบชนิดอิสระ เพราะ AIR เป็นจุดตรวจสำหรับการแปลง ไม่ใช่ IR แบบขนาน
HIR → AIR purity check → HIR to AIR lowering → AIR validation → AIR to MIR re-lowering → MIR backendสถาปัตยกรรมนี้มีแนวทางคล้าย JAX: รักษาตัวแทนแบบฟังก์ชันบริสุทธิ์ไว้สำหรับการแปลง แล้วค่อยลดรูปเป็น IR เชิงคำสั่งเมื่อถึงขั้นสุดท้าย AIR มีอยู่เพราะการทำออโตดิฟบน MIR เชิงคำสั่งจะต้องสร้างความบริสุทธิ์ขึ้นใหม่จากโค้ดที่ถูกลดรูปให้เป็นการกลายสภาพแล้ว
เลนเป้าหมาย CPU#
เป้าหมาย CPU จะรับ MIR และสร้างเป็นอาร์ติแฟกต์ที่เรียกใช้งานได้หรือข้อความสำหรับชุดเครื่องมือภายนอก Faber ส่งออกข้อความเมื่อทำได้ และพึ่งพาชุดเครื่องมือระดับล่างสำหรับขั้นตอนคอมไพล์สุดท้าย ซึ่งคล้ายกับคอมไพเลอร์ C ที่ส่งออกแอสเซมบลีให้แอสเซมเบลอร์และตัวลิงก์
FMIR — รันไทม์ MIR ของ Faber เอง#
FMIR คือเอกซีคิวเตอร์แพ็กเกจแบบเนทีฟต่อ MIR คอมไพเลอร์จะแยก MIR เป็นเพย์โหลดไบนารี แล้วห่อด้วยตัวโหลดเคอร์เนล Rust ขนาดสั้น ผลลัพธ์คือไฟล์ปฏิบัติการในตัวเองที่รัน MIR ผ่านสเต็ปเปอร์ภายในโปรเซสของ Faber โดยไม่ต้องติดตั้งรันไทม์แยกต่างหาก
| รูปแบบ | คำอธิบาย |
|---|---|
fmir-text | อิมเมจข้อความ FMIR ที่ตรวจสอบได้ที่ target/faber-mir/image.fmir.txt |
fmir | อิมเมจไบนารี FMIR แบบกระชับที่ target/faber-mir/image.fmir |
fmir-bin | รันเนอร์ในตัวเองที่ target/faber-mir/exe/run ซึ่งฝังไบต์ FMIR ไว้ภายใน |
ข้อความ LLVM#
Faber ส่งออก LLVM IR เป็นข้อความ (.ll) ไม่ใช่การสร้างโค้ด LLVM แบบผสานรวม IR ที่ส่งออกมีไว้สำหรับขั้นตอนของชุดเครื่องมือภายนอก โดยเครื่องมือ LLVM ปลายทางจะจัดการการตรวจสอบ การปรับให้เหมาะสม และการสร้างโค้ดเนทีฟ นี่คือเป้าหมายสำหรับการจัดเตรียมและการตรวจสอบ ไม่ใช่เส้นทางการสร้างโค้ดเนทีฟที่ฝังอยู่ในคอมไพเลอร์
WASM#
Faber ส่งออก WebAssembly ในรูปแบบข้อความ (.wat) และไบนารี (.wasm) Wasm ที่ส่งออกใช้การนำเข้าจากโฮสต์ภายนอก (สัญลักษณ์รันไทม์ faber_*) และตรวจสอบผ่าน wasm-tools validate Wasm เป็นเป้าหมายที่รองรับโดยมีข้อจำกัด — ใช้พิสูจน์ไปป์ไลน์การลดรูป MIR สำหรับรูปแบบมาตรฐานแบบเปิด แต่ไม่ใช่รันไทม์สำหรับส่งมอบแพ็กเกจ
| รูปแบบ | เป้าหมาย CLI | เอาต์พุต |
|---|---|---|
wasm-text | -t wasm-text (ชื่อแทน wat) | รูปแบบข้อความ WAT |
wasm | -t wasm | โมดูล Wasm แบบไบนารี |
TypeScript และ Go (HIR-direct)#
แม้โดยทั่วไปจะใช้สำหรับการส่งออกไฟล์ระดับแอปพลิเคชัน แต่ TypeScript และ Go ยังทำหน้าที่เป็นเป้าหมายสำหรับการพิสูจน์ด้วย โดยตรวจสอบว่าความหมายของ Faber แปลไปยังระบบชนิดที่ใช้งานอย่างแพร่หลายได้ แม้ว่าการคอมไพล์แพ็กเกจและการเรียกใช้รันไทม์จะยังคงเป็นความสามารถเฉพาะของ Rust ในปัจจุบัน
เลนเป้าหมาย GPU#
WGSL (ผ่าน WGPU)#
Faber ส่งออกซอร์ส compute shader ของ WGSL ผ่านไปป์ไลน์ MIR WGSL ที่ส่งออกจะถูกตรวจสอบผ่าน naga (30.x) และมี sidecar สำหรับการสะท้อนข้อมูลเมตาของ bind group ขอบเขตนี้ครอบคลุมเซตย่อยของเคอร์เนลที่ปลอดภัยต่ออุปกรณ์ โดยรองรับ device view แบบ f32 มิติ 1 และปฏิเสธ view มิติ 2 WGSL ไม่ใช่รันไทม์สำหรับเปิดใช้ GPU — Faber ส่งออกซอร์สเชดเดอร์ แต่การทำงานจริงต้องใช้รันไทม์ WebGPU ภายนอก
Metal (พักไว้)#
การส่งออกข้อความ compute shader ของ Metal ได้รับการออกแบบและพัฒนาไปบางส่วนแล้ว แต่ขณะนี้พักไว้ก่อน สถาปัตยกรรมใช้รูปแบบเดียวกับ WGSL: Faber ส่งออกซอร์ส Metal Shading Language สำหรับเซตย่อยของเคอร์เนลที่ปลอดภัยต่ออุปกรณ์ ขณะที่ชุดเครื่องมือภายนอกจัดการการคอมไพล์และการเรียกใช้ มีแผนกลับมาดำเนินงานต่อ
หมายเหตุด้านสถาปัตยกรรม#
สถาปัตยกรรมการคอมไพล์ของ Faber มีแนวคิดคล้ายกับการทำงานของคอมไพเลอร์ Rust Rust ลดรูปผ่าน HIR → MIR → LLVM IR และฝังชุดเครื่องมือ LLVM ไว้โดยตรงสำหรับการสร้างโค้ดเนทีฟขั้นสุดท้าย ส่วน Faber ใช้แนวทางที่ยืดหยุ่นกว่า โดยส่งออกข้อความสำหรับชุดเครื่องมือภายนอก (ข้อความ LLVM, WGSL, Metal และ WAT) แทนการฝังชุดเครื่องมือเหล่านั้น ขณะเดียวกันยังคงสงวนการส่งออกโค้ดโดยตรงไว้สำหรับรันไทม์ของตนเอง (FMIR) และเป้าหมายแพ็กเกจหลักของตน (Rust ซึ่ง Cargo และ rustc จัดการไปป์ไลน์ขั้นถัดไป)
แนวทางการส่งออกเป็นข้อความทำให้ Faber ไม่จำเป็นต้องรวม LLVM รันไทม์ Wasm หรือไดรเวอร์ GPU ไว้ภายใน เพราะสิ่งเหล่านี้ยังคงเป็นดีเพนเดนซีภายนอกที่ผู้ใช้เลือกเอง ข้อแลกเปลี่ยนคือ Faber ไม่สามารถเสนอการบิลด์ด้วยคำสั่งเดียวสำหรับทุกเป้าหมายได้ ผู้ใช้ต้องติดตั้งชุดเครื่องมือที่เหมาะสมสำหรับแบ็กเอนด์ที่เลือก
สรุปเป้าหมาย#
| เป้าหมาย | IR | กลุ่ม | บิลด์ | รัน | แพ็กเกจ |
|---|---|---|---|---|---|
Rust | HIR | CPU | ใช่ | ใช่ | ใช่ |
fmir / fmir-bin | MIR | CPU | ใช่ | ใช่ | ใช่ |
Faber (format) | HIR | — | ไม่ | ไม่ | ไม่ |
TypeScript | HIR | CPU | ไม่ | ไม่ | ไม่ |
Go | HIR | CPU | ไม่ | ไม่ | ไม่ |
LLVM text | MIR | CPU | ไม่ | ไม่ | ไม่ |
WASM / WAT | MIR | CPU | ไม่ | ไม่ | ไม่ |
WGSL | MIR | GPU | ไม่ | ไม่ | ไม่ |
Metal (hold) | MIR | GPU | ไม่ | ไม่ | ไม่ |
`build`, `run` และ `package` หมายถึงเวิร์กโฟลว์ของ Faber ชุดเครื่องมือภายนอก (rustc, wasm-tools, naga) จะจัดการการคอมไพล์ขั้นสุดท้ายสำหรับเป้าหมายที่ส่งออกเป็นข้อความ
Compiler performance#
ฟรอนต์เอนด์ของ Radix มีอัตราการขยายโดยประมาณเป็นเส้นตรงตามขนาดซอร์ส โดยทำงานภายในกระบวนการเดียวและใช้เธรดเดียว
เวลาในการคอมไพล์ฟรอนต์เอนด์#
| ขนาดโปรแกรม | ซอร์ส | เวลาคอมไพล์มัธยฐาน |
|---|---|---|
| 100 ฟังก์ชัน / ประมาณ 650 บรรทัด | ประมาณ 10 KB | ประมาณ 0.6 มิลลิวินาที |
| 500 ฟังก์ชัน / ประมาณ 3.3K บรรทัด | ประมาณ 52 KB | ประมาณ 3 มิลลิวินาที |
| 1,000 ฟังก์ชัน / ประมาณ 6.5K บรรทัด | ประมาณ 105 KB | ประมาณ 6 มิลลิวินาที |
| 5,000 ฟังก์ชัน / ประมาณ 32K บรรทัด | ประมาณ 530 KB | ประมาณ 37 มิลลิวินาที |
ตัวอย่างจริงที่ใหญ่ที่สุดในปัจจุบันมีประมาณ 140 บรรทัด ซึ่งต่ำกว่าระดับสัญญาณรบกวนมาก
ต้นทุนของแบ็กเอนด์ (เป้าหมาย Rust)#
สำหรับ faber build เวลาที่ผู้ใช้รับรู้ส่วนใหญ่ถูกใช้ไปกับ Cargo/rustc
ไม่ใช่ฟรอนต์เอนด์ของ Faber:
| ระยะ | ต้นทุน |
|---|---|
คอมไพล์ดีเพนเดนซีของ faber แบบแคชว่าง (ครั้งเดียวต่อตำแหน่งเป้าหมาย) | ประมาณ 2.8 วินาที |
คอมไพล์ดีเพนเดนซีของ tokio แบบแคชว่าง (เฉพาะเมื่อต้องใช้) | ประมาณ 2.3 วินาที |
| บิลด์ต่อโปรแกรมแบบวอร์ม (ดีเพนเดนซีอยู่ในแคช) | ประมาณ 30–110 มิลลิวินาที |
| โอเวอร์เฮดจากการเรียก Cargo ต่อโปรแกรม | ประมาณ 400 มิลลิวินาที |
การคอมไพล์แบบเพิ่มทีละส่วน#
crate faber-runtime จะคอมไพล์หนึ่งครั้งต่อตำแหน่งเป้าหมาย และแคชเป็นอาร์ติแฟกต์ .rlib:
| สิ่งที่คุณเปลี่ยน | crate faber-runtime | โปรแกรมของคุณ |
|---|---|---|
| ซอร์สของโปรแกรม | ใช้แคช | คอมไพล์ใหม่ |
norma/src/*.fab (ซอร์ส Faber) | ใช้แคช | คอมไพล์ใหม่ |
faber/runtime/rust/src/*.rs | คอมไพล์ใหม่หนึ่งครั้ง | คอมไพล์ใหม่ |
กับดักที่ควรหลีกเลี่ยงคือการบิลด์แต่ละโปรแกรมลงใน target/ ใหม่
ให้ใช้ --target-dir ร่วมกัน เพื่อให้ .rlib ที่อยู่ในแคชยังคงพร้อมใช้งาน —