1 คะแนน โดย GN⁺ 2025-01-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Wild เป็นลิงเกอร์ที่มุ่งให้การลิงก์ระหว่างการพัฒนาแบบวนซ้ำทำได้เร็วมาก แม้ยังไม่ได้ implement การลิงก์แบบ incremental แต่การลิงก์แบบ non-incremental เพียงอย่างเดียวก็อยู่ในระดับที่เร็วแล้ว
  • mold ซึ่งเป็นลิงเกอร์ความเร็วสูงที่มีอยู่เดิม ไม่ทำ incremental link และไม่มีแผนจะทำ จุดนี้จึงเป็นจุดเริ่มต้นของ Wild โดย Wild เขียนด้วย Rust และมีเป้าหมายเพื่อรับมือกับความซับซ้อนของ incremental linking
  • แพลตฟอร์มที่รองรับในปัจจุบันคือ x86-64, ARM64, RISC-V, LoongArch64, PPC64LE บน Linux และรองรับ static binary, static-PIE, binary แบบ dynamic link, shared object, Rust proc-macro, debug information เป็นต้น
  • สามารถใช้เป็น drop-in replacement ที่ GCC·Clang เรียกเหมือนลิงเกอร์เดิมได้ และเชื่อมใช้กับ Cargo, ระบบ build ของ C/C++, และ wild-action สำหรับ CI ได้
  • ยังไม่ได้ implement incremental linking, linker script ที่ซับซ้อนกว่า, การรองรับ Mach-O และ Windows และต้องตรวจสอบว่าถูกใช้ลิงก์จริงหรือไม่ด้วย readelf หรือ strings โดยดูข้อความ Linker: Wild version... ใน binary

เป้าหมายและตำแหน่งของ Wild

  • Wild เป็นลิงเกอร์ที่มุ่งให้การลิงก์ระหว่างการพัฒนาแบบวนซ้ำทำได้เร็วมาก
  • แผนระยะยาวคือ implement incremental linking แต่ปัจจุบันยังไม่ได้ implement
  • ระบุว่าแม้ไม่มี incremental linking ประสิทธิภาพของ non-incremental linking ก็เร็วอยู่แล้ว
  • mold นั้นเร็วมากอยู่แล้ว แต่ไม่ทำ incremental linking และผู้เขียนระบุว่าไม่มีแผนจะทำ incremental linking นี่คือเหตุผลที่ Wild ถูกสร้างเป็นลิงเกอร์แยกต่างหาก
  • Wild เขียนด้วย Rust และคาดหวังว่าจะสามารถจัดการความซับซ้อนของ incremental linking ด้วย Rust ได้

วิธีติดตั้ง

  • สามารถดาวน์โหลด release tarball ได้จาก releases page จากนั้นแตกไฟล์แล้วคัดลอก binary wild ไปยังตำแหน่งที่อยู่ใน PATH
  • หากมี cargo-binstall สามารถติดตั้งด้วยคำสั่งต่อไปนี้
cargo binstall wild-linker
  • คำสั่งติดตั้งด้วย Homebrew มีดังนี้
brew install wild-linker/wild/wild
  • หากต้องการ build release ล่าสุดจาก crates.io ให้ใช้คำสั่งต่อไปนี้
cargo install --locked wild-linker
  • หากต้องการติดตั้งโค้ด unreleased ล่าสุดจาก Git ให้ใช้คำสั่งต่อไปนี้
cargo install --locked --bin wild --git https://github.com/wild-linker/wild.git wild-linker
  • Wild เวอร์ชันเสถียรใน Nixpkgs สามารถใช้ผ่าน pkgs.useWildLinker pkgs.stdenv ได้
  • สำหรับ Git revision ล่าสุดที่ยังไม่เสถียร ให้ดูเอกสาร nix/nix.md

วิธีใช้เป็นลิงเกอร์เริ่มต้น

  • Wild ออกแบบให้เป็น drop-in replacement ซึ่งใช้ในลักษณะที่ GCC หรือ Clang เรียกใช้งานได้
  • ตัวเลือกมีดังนี้
    • ตัวเลือกเฉพาะ Clang --ld-path=wild
    • -fuse-ld=wild ของ GCC 16.1 ขึ้นไปและ Clang
      • Clang ต้องมี binary หรือ symbolic link ชื่อ ld.wild
    • -B <path> ซึ่งรองรับทั่วไป
      • <path> คือไดเรกทอรีที่มี ld ซึ่งชี้ไปยัง wild
  • Rust และ Cargo

    • ใน ~/.cargo/config.toml สามารถใช้ Clang ร่วมกับ --ld-path=wild ได้
    [target.x86_64-unknown-linux-gnu]
    linker = "clang"
    rustflags = ["-Clink-arg=--ld-path=wild"]
    
    • หรือสามารถใช้ -fuse-ld=wild ได้
    [target.x86_64-unknown-linux-gnu]
    
    # linker = "clang" # Uncomment this line if your GCC is older than version 16.
    rustflags = ["-Clink-arg=-fuse-ld=wild"]
    
  • ระบบ build ของ C/C++

    • ใน autotools, CMake, meson เป็นต้น โดยทั่วไปแค่ตั้งค่า LDFLAGS ก็เพียงพอ
    export LDFLAGS="${LDFLAGS} -fuse-ld=wild"
    
    • ใน GCC เวอร์ชันเก่า สามารถสร้าง symbolic link ld ที่ชี้ไปยัง wild แล้วส่งไดเรกทอรีนั้นผ่าน -B ได้
    ln -s /usr/bin/wild /tmp/ld
    
    export CFLAGS="${CFLAGS} -B/tmp"
    export CXXFLAGS="${CXXFLAGS} -B/tmp"
    export LDFLAGS="${LDFLAGS} -B/tmp"
    
    • ระบบ build เหล่านี้อาจซับซ้อนได้ จึงแนะนำวิธีตรวจสอบด้วย readelf ว่า Wild ถูกใช้ลิงก์ binary จริงหรือไม่
  • การตั้งค่า Cargo สำหรับ Illumos

    • บน Illumos ต้องระบุ absolute path ของ Clang และต้องส่ง Wild เป็น absolute path ด้วย
    • หากไม่ระบุ absolute path ของ Wild อาจถูก delegate ไปยัง GNU ld หรือ Sun ld อย่างเงียบ ๆ
    [target.x86_64-unknown-illumos]
    
    # Absolute path to clang - on OmniOS this is likely something like /opt/ooce/bin/clang.
    linker = "/usr/bin/clang"
    
    rustflags = [
    
    # Will silently delegate to GNU ld or Sun ld unless the absolute path to Wild is provided.
        "-Clink-arg=-fuse-ld=/absolute/path/to/wild"
    ]
    

สถานะการรองรับและรายการที่ยังไม่รองรับ

  • แพลตฟอร์มและสถาปัตยกรรมที่รองรับในปัจจุบันมีดังนี้
    • x86-64 on Linux

    • ARM64 on Linux

    • RISC-V(riscv64gc) on Linux

      • LoongArch64 on Linux
      • อยู่ในสถานะรองรับระยะแรก
      • PPC64LE on Linux
      • อยู่ในสถานะรองรับระยะแรก
      • ฟีเจอร์ที่ทำงานได้มีดังนี้ แต่มีหมายเหตุว่าอาจมีบั๊ก
      • output เป็น binary แบบ static linked non-relocatable
      • output เป็น position-independent binary แบบ static linked หรือ static-PIE
      • output เป็น binary แบบ dynamic link
      • output เป็นไฟล์ shared object .so
      • Rust proc-macro ที่ลิงก์ด้วย Wild
      • ผ่านการทดสอบกับ crate ส่วนใหญ่ที่มียอดดาวน์โหลดสูงบน crates.io
      • debug information
      • รองรับ GNU jobserver
      • รองรับ linker script บางส่วน
      • ดูรายละเอียดได้ที่ linker script support matrix
      • Linker plugin LTO
      • มี known issues
      • รายการใหญ่ที่ยังไม่ได้ implement มีดังนี้ โดยเรียงใกล้เคียงตามลำดับความสำคัญปัจจุบัน
    • incremental linking

      • linker script ที่ซับซ้อนกว่า
      • รองรับ Mach-O
      • รองรับ Windows

ตรวจสอบว่าใช้ Wild หรือไม่

  • readelf สามารถติดตั้งได้จากแพ็กเกจ binutils และใช้คำสั่งต่อไปนี้เพื่อตรวจสอบสตริงใน section .comment
readelf --string-dump .comment my-executable
  • หากมีบรรทัดลักษณะต่อไปนี้ แปลว่าเป็น binary ที่ลิงก์ด้วย Wild
Linker: Wild version 0.1.0
  • strings ก็ใช้งานได้จากแพ็กเกจ binutils เช่นกัน และสามารถตรวจสอบด้วยคำสั่งต่อไปนี้ได้ด้วย
strings my-executable | grep 'Linker:'

Benchmark และเป้าหมายการทดสอบ

  • เป้าหมายของ Wild คือการเป็นลิงเกอร์ที่เร็วมากในที่สุดผ่าน incremental linking
  • ยังมีเป้าหมายให้ non-incremental linking และ initial link เมื่อเปิดใช้ incremental linking ทำได้เร็วที่สุดเท่าที่เป็นไปได้
  • benchmark ทั้งหมดรันภายใต้เงื่อนไขที่ output ไปยัง tmpfs
  • วิธีรัน benchmark สรุปไว้ใน BENCHMARKING.md
  • ระบบที่ใช้เป็นเป้าหมาย benchmark มีดังนี้
  • ตัวอย่าง benchmark รวมถึงเวลา link และการใช้หน่วยความจำของ Chromium, เวลา link ของ librustc-driver, เวลา link ของ Wild เอง, และเวลา link ของ rust-analyzer บน Raspberry Pi 5

ตัวอย่างการลิงก์โค้ด Rust และข้อมูลโปรเจกต์

  • ตัวอย่างการใช้ Wild เพื่อ build และทดสอบ crate ใน cargo test มีดังนี้
  • คำสั่งนี้รันสำเร็จกับ crate ยอดนิยมบางตัว เช่น ripgrep, serde, tokio, rand, bitflags
  • binary wild ต้องอยู่ใน PATH และเนื่องจาก GCC ไม่อนุญาตให้ใช้ลิงเกอร์ใดก็ได้ จึงจำเป็นต้องติดตั้ง Clang
RUSTFLAGS="-Clinker=clang -Clink-args=--ld-path=wild" cargo test
  • หาก symbolic link ld.wild ชี้ไปยัง wild ก็สามารถใช้วิธีต่อไปนี้ได้เช่นกัน
RUSTFLAGS="-Clinker=clang -Clink-args=-fuse-ld=wild" cargo test
  • หากต้องการใช้ Wild เป็นลิงเกอร์สำหรับโค้ด Rust ใน CI ให้ดู wild-action
  • ข้อมูลการมีส่วนร่วมอยู่ใน CONTRIBUTING.md และภาพรวมการออกแบบระดับสูงอยู่ใน DESIGN.md
  • การสนทนาเกี่ยวกับ Wild ดำเนินอยู่บน Zulip server
  • บล็อกของ David มีบทความจำนวนมากที่พูดถึงหลายแง่มุมของลิงเกอร์ Wild
  • ใบอนุญาตเลือกได้ระหว่าง Apache License 2.0 หรือ MIT license

1 ความคิดเห็น

 
GN⁺ 2025-01-25
ความคิดเห็นจาก Hacker News
  • หลังจาก mold ถูก เปลี่ยนไลเซนส์จาก AGPL เป็น MIT (เป็นส่วนหนึ่งของรีลีส mold 2.0) ผมคิดว่าความจำเป็นที่จะต้องสร้างลิงเกอร์เร็ว ๆ อีกตัวทั่วโลกคงลดลงไปมากแล้ว เลยไม่คิดว่าจะมีโปรเจกต์แบบนี้ออกมา
    แถมในบางกรณียัง เร็วกว่า mold 2 เท่า อยู่แล้ว ยิ่งคาดไม่ถึงเข้าไปอีก เลยตั้งใจจะคอยดูว่ามันจะพัฒนาไปอย่างไร และขอให้ผู้เขียนโชคดี

    • mold ไม่มีแผนจะทำ incremental linking ดังนั้นจึงมีเหตุผลสำคัญที่ลิงเกอร์ตัวอื่นควรมีอยู่
      ลิงเกอร์ของ Microsoft มี incremental linking เป็นค่าเริ่มต้นมาตั้งหลายสิบปีแล้ว แต่บน Linux ยังไม่มี incremental linker ที่พร้อมใช้ในโปรดักชัน นี่ก็น่าอายอยู่เหมือนกัน
    • ทำไมความต่างระหว่าง AGPL กับ MIT ถึงสำคัญในลิงเกอร์?
    • ไม่แน่ใจว่าสถานะการรองรับ Windows ของ mold เป็นอย่างไร
      จาก issue บน GitHub ดูเหมือนผู้เขียนตอนแรกพยายามจะรองรับ แล้วก็ย้ายการรองรับ Windows ไปไว้ที่ลิงเกอร์ sold แต่ sold ก็ถูกเก็บเข้าคลังไปเมื่อไม่นานนี้ เลยงงว่าสุดท้ายคือไม่มีการรองรับ Windows หรือผมเข้าใจลำดับเรื่องผิดกันแน่
    • อาจเป็นผมใช้ผิดเองก็ได้ แต่ถ้าใช้ LTO ซึ่งก็น่าจะต้องใช้ mold ไม่ได้เร็วขึ้นเลย
    • เดี๋ยวนะ ของที่เป็น GPL สามารถ เปลี่ยนไลเซนส์เป็น MIT ได้ด้วยเหรอ?
  • เคยลองดูมาก่อน แต่ยังไม่แน่ใจว่า พร้อมใช้ในโปรดักชัน แล้วหรือยัง
    ถ้าดูจาก README เหมือนจะยังไม่พร้อม ผมเลยยังใช้ mold อยู่
    ถ้าเป็นผู้ใช้ macOS ทาง Apple ออกลิงเกอร์ตัวใหม่เมื่อประมาณ 1–2 ปีก่อน และนั่นทำให้ผู้เขียน mold หยุดทำเวอร์ชัน macOS
    ถ้าจะใช้กับ Rust ให้ใส่แบบนี้ใน config.toml

    [target.aarch64-apple-darwin]

    rustflags = [

    "-C",

    "link-arg=-fuse-ld=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",

    "-C",

    "link-arg=-ld_new",

    ]

    • ผู้เขียนพูดไว้ค่อนข้างชัดเจนว่ายัง ไม่ควรใช้ในโปรดักชัน
    • mold ก็ไม่ได้ใช้ในโปรดักชัน ใช้เป็น สำหรับการพัฒนา
    • ทุกวันนี้ลิงเกอร์ตัวใหม่เป็นค่าเริ่มต้นอยู่แล้วไม่ใช่เหรอ? ไม่ค่อยแน่ใจว่าเพิ่มอันนั้นแล้วยังได้ผลไหม
    • ช่วยยืนยันได้ไหมว่าตำแหน่งนั้นยังถูกบน Sequioa หรือเปล่า?
      ผมติดตั้งเครื่องมือบรรทัดคำสั่งแล้ว แต่มีแค่ /usr/bin/ld กับ /usr/bin/ld-classic
  • คงน่าสนใจถ้าคอมไพเลอร์ C/C++ ตัดขั้นกลางที่เรียกว่าการลิงก์ออกไป แล้ว build ทั้งโปรแกรมเป็นหน่วยเดียว
    ถ้าคอมไพเลอร์มองเห็นทั้งโปรแกรมตั้งแต่แรก ก็ไม่จำเป็นต้องมี LTO เอง
    เพื่อ incremental build ก็คงต้องเก็บผลลัพธ์บางส่วนของการ build ไว้ แต่ไม่ใช่ในรูป object file ต้องเป็น metadata ที่รู้ว่าค้ดที่สร้างมาจากที่ไหนและมี dependency อะไร เพื่อให้เปลี่ยนเฉพาะส่วนที่ถูกต้องได้
    ทุกวันนี้ไลบรารีภายนอกส่วนใหญ่ลิงก์แบบไดนามิกอยู่แล้ว จึงไม่จำเป็นต้อง build จากซอร์ส และการเอาลิงเกอร์ออกก็ไม่ทำให้ dependency ที่ไม่เปิดเผยมีปัญหา
    ถ้ายังไม่พอ ก็ให้คอมไพเลอร์รับ object file ได้ด้วย เพื่อจัดการกรณี legacy หรือกรณีพิเศษที่ต้องลิงก์แบบสแตติกเข้าไปในไบนารี

    • SQLite3 เอาทุกอย่างมาต่อกันเป็น หน่วยคอมไพล์เดียว
      น่าจะมีคนใช้วิธีนี้อยู่แล้วมากกว่าที่คิด

      https://sqlite.org/amalgamation.html

  • ความสนใจในลิงเกอร์ที่รวดเร็วเพิ่มขึ้นมากเพราะ การยอมรับและความนิยมของ Rust
    แม้แต่ไบนารี Rust แบบ static link ขนาดพอประมาณ ก็อาจใช้เวลาหลายนาทีในขั้นตอนลิงก์ของการคอมไพล์โหมด release (เมื่อใช้ mold)
    นี่ไม่ใช่ปัญหาเฉพาะของ Rust แต่โดยรวมเป็นผลจาก static link ที่เข้มงวด การปรับแต่งขั้นสูงในเวลาลิงก์อย่าง LTO และ BOLT ที่ LLVM ให้มา และเสียงบ่นเรื่องเวลา compile ในชุมชน Rust มารวมกัน
    เพราะ Rust มีความสัมพันธ์แน่นแฟ้นกับ LLVM และแทบจะพึ่งพามัน จึงกลายเป็นภาษาที่นำเวทมนตร์ช่วงลิงก์ของ LLVM มาใช้แพร่หลายที่สุด ส่วน C++ ก็เจอปัญหาเดียวกันได้ แต่ตอนนั้นคนมักจะมองว่าเป็นความผิดของ toolchain มากกว่าของภาษา
    ผมจับตาดู wild มาสักพักเพราะมีศักยภาพจะเป็น ลิงเกอร์แบบ incremental ที่ปรับแต่งประสิทธิภาพได้ แต่พูดตรง ๆ ก่อนที่มันจะทำ incremental linking ได้จริง ผมไม่มีแรงจูงใจจะลองจับเลย

    • C++ มีคอมไพเลอร์บางตัวที่รองรับ incremental compilation และ incremental linking เลยคอมไพล์ได้เร็วกว่า Rust มาก
      อีกอย่าง ecosystem ของ C/C++ มีวัฒนธรรมยอมรับไลบรารีแบบไบนารี จึงมีหลายกรณีที่พอ clone repository หรือเปลี่ยน branch สำหรับพัฒนา ก็ไม่ต้องคอมไพล์ทั้งโลกใหม่ แค่คอมไพล์แอปพลิเคชันของตัวเองก็พอ
    • ปัญหานี้แก้ด้วย Wasm แล้ว
      ถ้าให้ shell แอปภายนอกเรียก business logic ที่เป็น Wasm ก็ต้องคอมไพล์ใหม่แค่ logic ภายใน และ shell แอปภายนอกไม่ต้อง restart ด้วยซ้ำ
  • ปี 2008: ลิงเกอร์ใหม่ gold ที่ทำมาให้เร็วกว่า GNU ld

    ราวปี 2015: ลิงเกอร์ทดแทนแบบ drop-in lld ที่เร็วกว่า gold อย่างน้อย 2 เท่า

    ปี 2021: ลิงเกอร์ใหม่ mold ที่เร็วกว่า lld หลายเท่า

    ปี 2025: ลิงเกอร์ใหม่ wild...

    • ไม่ค่อยมีใครพูดถึง แต่ทั้งหมดนี้เป็นไปได้ด้วยการแลกกับการไม่ implement ฟีเจอร์ที่มีประโยชน์จำนวนมากซึ่งโปรแกรมจริง ๆ ใช้กัน
    • ไม่แน่ใจว่านี่เป็นคำพูดเชิงลบ เชิงบวก หรือแค่สรุปประวัติสั้น ๆ แต่ข้อเท็จจริงที่ว่ายังรีดประสิทธิภาพจากลิงเกอร์ได้อีกก็น่ามีกำลังใจทีเดียว
    • gold มีกำหนดจะถูกลบออกใน binutils 2.44.0 ดังนั้นถือว่าตายอย่างเป็นทางการแล้ว
    • บน Windows ยังมี The RAD Linker ด้วย แม้จะยังอยู่ช่วงเริ่มต้นก็ตาม
  • เรื่องที่เกี่ยวข้อง มีหนังสือเก่าแต่ดีของ John Levine ชื่อ Linkers and Loaders
    เป็นเล่มสุดท้ายในรายการด้านล่าง

    https://www.johnlevine.com/books.phtml

    ผมอ่านเมื่อหลายปีก่อนและค่อนข้างน่าสนใจ ถือเป็นหนังสือมาตรฐานของด้านนี้
    อย่างที่เห็นจากลิงก์ เขายังเขียนหนังสือคอมพิวเตอร์ยอดนิยมเล่มอื่น ๆ ด้วย

  • ดูมีอนาคตดีทีเดียว
    เขียนด้วย Rust ตั้งแต่แรก และเป้าหมายคือให้เร็วพร้อมรองรับ incremental linking
    ถ้าจะใช้กับ Rust ก็น่าจะใช้ gcc เป็น linker driver ได้เหมือนกัน
    ใน .cargo/config.toml ของโปรเจกต์:

    [target.x86_64-unknown-linux-gnu]

rustflags = ["-C", "link-arg=-fuse-ld=wild"]

นอกเรื่องนิดหนึ่ง แต่ทำไม Rust ถึงต้องไปผูกกับ gcc หรือ clang ตรงนี้ด้วย? มีฟีเจอร์อะไรที่ขาดไปหรือเปล่า?

  • น่าเสียดายที่ gcc ไม่รับลิงเกอร์ใด ๆ ผ่านแฟล็ก -fuse-ld=
    ลิงเกอร์ที่รับมีแค่ bfd, gold, lld, mold เท่านั้น
    ทำให้ gcc เรียก wild เป็นลิงเกอร์ได้ก็จริง แต่ตอนนี้ต้องสร้างไดเรกทอรีที่มีลิงเกอร์ wild อยู่ แล้วเปลี่ยนชื่อไบนารีหรือลิงก์สัญลักษณ์เป็น "ld" จากนั้นส่ง -B/path/to/directory/containing/wild ให้ gcc
    เหตุผลที่ Rust ไม่เรียกลิงเกอร์โดยตรง แต่เรียกลิงเกอร์ผ่าน gcc หรือ clang คือคอมไพเลอร์ C รู้แฟล็กลิงเกอร์ที่จำเป็นสำหรับลิงก์กับ libc และ C runtime บนแพลตฟอร์มปัจจุบัน
    เช่น Scrt1.o, crti.o, crtbeginS.o, crtendS.o, crtn.o เป็นต้น

  • เพราะคอมไพเลอร์ Rust สร้าง IR bytecode ไม่ใช่ภาษาเครื่อง

  • สงสัยว่า ในกรณีที่ไม่ใช่ incremental มีเหตุผลเชิงทฤษฎีอะไรที่ทำให้สิ่งนี้เร็วกว่า mold ได้?
    “เพราะเป็น Rust” ใช้อธิบายได้ดีในหลายเรื่อง แต่ไม่ได้อธิบายข้อได้เปรียบด้านประสิทธิภาพที่คาดหวัง
    ถ้าเป็น “เพราะมีโอกาสทำ parallel processing ที่ความยากต่ำ ซึ่ง Rust ช่วยให้ใช้ประโยชน์ได้ง่าย” ก็น่าสนใจ แต่ก็ไม่ได้ระบุหรือบอกเป็นนัยไว้เลย

    • ผมก็ไม่รู้แน่ชัด และหลัก ๆ เพราะไม่คุ้นกับโค้ดเบสของ Mold
      เบาะแสอย่างหนึ่งคือเคยได้ยินว่า Mold จะเร็วขึ้นประมาณ 10% ถ้าใช้ allocator ที่เร็วกว่าอย่าง mimalloc
      ผมลองใช้ mimalloc กับ Wild แล้ว แต่ไม่เห็นความเร็วเพิ่มขึ้นที่วัดได้
      จากตรงนี้ดูเหมือนว่า Mold ใช้ allocator มากกว่า Wild และใน Wild ก็พยายามอย่างชัดเจนที่จะปรับลดจำนวนครั้งของ heap allocation
      โดยรวมแล้วผมมองว่าเป็นความต่างของการตัดสินใจด้านการออกแบบ
      ถ้าถามว่าสิ่งนี้เกี่ยวกับ Rust อย่างไร ผมมั่นใจว่าถ้าพอร์ต Wild จาก Rust ไปเป็น C หรือ C++ ประสิทธิภาพก็น่าจะเกือบเหมือนเดิม
      เพียงแต่ใน Rust ด้วย borrow checker ทำให้แพตเทิร์นโค้ดที่โอเค อาจกลายเป็นกับดักใน C หรือ C++ และทำให้ดูแลรักษายาก
      เมื่อก่อนตอนเขียน C++ ผมมักเขียนแบบ defensive มากกว่า แม้ต้องยอมเสียประสิทธิภาพเล็กน้อย แต่ใน Rust ผมรู้ว่าคอมไพเลอร์ช่วยดูให้ จึงเขียนได้กล้ากว่ามาก
  • บังเอิญจัง
    เมื่อหนึ่งชั่วโมงก่อนผมเพิ่งเทียบประสิทธิภาพ wild, mold, ld ในโปรเจกต์ C ที่กำลังทำอยู่
    มี 23,000 บรรทัด 172 ไฟล์ และ gcc+ld ใช้ user time ประมาณ 23.4 วินาที, gcc+mold 22.5 วินาที, gcc+wild 21.8 วินาที
    ดังนั้นผมคิดว่าถ้าเป็นโปรเจกต์ที่มีโครงสร้างดี เวลา link อาจไม่ใช่ปัญหาใหญ่นัก

    • ฟังดูเหมือนเป็นการ build ใหม่ตั้งแต่ต้น
      ในกรณีนั้นเวลาส่วนใหญ่ใช้ไปกับการ compile โค้ด ไม่ใช่ linking
      ข้อดีของลิงเกอร์เร็วจะเห็นชัดที่สุดใน iterative development
      กล่าวคือหลังจากแก้โค้ดเล็กน้อยแล้ว build ใหม่และรันผลลัพธ์ คอมไพเลอร์มักแทบไม่มีอะไรต้องทำ แต่ linking ยังต้องทำใหม่ตั้งแต่ต้น จึงมักกลายเป็นเวลาหลัก
    • เวลา link สำคัญตอน build อะไรอย่าง Chrome ไม่ใช่โปรเจกต์เล็ก ๆ
    • ลิงเกอร์เร็วโดยทั่วไปมีประโยชน์ในการลดรอบการ edit ในสถานการณ์ incremental compilation
    • แล้ว ld.lld ล่ะ?
  • “เบนช์มาร์กนี้รันบนแล็ปท็อปของ David Lattimore (System76 Lemur Pro รุ่นปี 2020) ซึ่งมี 4 คอร์ (8 เธรด) และ RAM 42GB

    https://news.ycombinator.com/item?id=33330499

    ขอเสริมว่าไม่ได้จะบอกว่า wild บวมเกินไป
    ถ้ามีปัญหา ปัญหาน่าจะอยู่ที่ซอฟต์แวร์ที่ถูกพัฒนาด้วยสิ่งนั้น และคอมพิวเตอร์ของคนที่จะใช้ซอฟต์แวร์เหล่านั้นมากกว่า

    • https://news.ycombinator.com/item?id=42896619

      “... RAM มี 16GB และอัปเกรดไม่ได้...”

    • พูดกึ่งล้อเล่นนะ แต่ถ้าคนเขียนโค้ด Rust ก็น่าจะมี RAM 32GB อยู่แล้ว
      ส่วนตัวแล้ว การอัปเกรดแล็ปท็อปเป็น 64GB โดยยอมเสียสละทุกอย่างอื่นอย่างแท้จริง แทบจะเป็นการตัดสินใจที่ยอดเยี่ยม
      ที่บอกว่าแทบจะ เพราะผมน่าจะไม่ทุ่มทั้งหมดไปกับ RAM แต่ควรเอาเงินไปลงทั้ง RAM และจอด้วย
      ข้อเสียเดียวคือการจัดการแท็บที่เปิดไว้สัปดาห์ละครั้ง กลายเป็นงานที่กินเวลาทั้งเย็นไปแล้ว