- Bun का पैकेज इंस्टॉलेशन मौजूदा पैकेज मैनेजरों की तुलना में बहुत तेज़ गति से काम करता है
- तेज़ इंस्टॉलेशन की कुंजी system programming दृष्टिकोण और system calls को न्यूनतम करना है
- Zig भाषा आधारित native coding, binary cache का उपयोग, और OS-विशिष्ट optimization जैसी सूक्ष्म रणनीतियों के माध्यम से प्रदर्शन बेहतर किया गया है
- tarball extraction और file copy प्रक्रिया में भी hardware की विशेषताओं का उपयोग करने वाले high-performance तरीकों को अपनाया गया है
- dependency graph और lockfile जैसे क्षेत्रों में data structure optimization के जरिए CPU cache efficiency और memory accessibility बढ़ाई गई है
Bun Install तेज़ क्यों है
- Bun का
bun install औसतन npm से 7 गुना, pnpm से 4 गुना, और yarn से 17 गुना तेज़ पैकेज इंस्टॉलेशन प्रदर्शन देता है
- यह सिर्फ़ benchmark का परिणाम नहीं है, बल्कि इसलिए संभव है क्योंकि पैकेज इंस्टॉलेशन की समस्या को JavaScript नहीं बल्कि system programming के नज़रिए से देखा गया है
- system calls को कम करना, manifest binary caching, tarball extraction optimization, और OS native file copy जैसे कई स्तरों पर performance optimization को सक्रिय रूप से लागू किया गया है
Node.js और पैकेज मैनेजर आर्किटेक्चर की सीमाएँ
- 2009 में Node.js के आने के बाद, event loop और thread pool आधारित asynchronous IO मॉडल पैकेज मैनेजरों तक भी फैल गया
- उस समय hardware की सीमाएँ थीं, जैसे धीमी disk और धीमा network, इसलिए asynchronous IO और ज़्यादा system calls वाली रणनीति उचित थी
- लेकिन आधुनिक सिस्टम में NVMe SSD, तेज़ network, और high-performance CPU आम हो चुके हैं, और असली bottleneck अब IO नहीं बल्कि system call overhead है
System call और mode switch की लागत
- जब कोई program file read जैसे काम की मांग करता है, तो उसे user mode से kernel mode में switch करना पड़ता है, और इस प्रक्रिया में महंगे CPU cycles (1000~1500 cycles) खर्च होते हैं
- पैकेज इंस्टॉलेशन में मूल रूप से दसियों हज़ार से लेकर लाखों तक system calls लगते हैं, इसलिए सिर्फ़ context switching की लागत ही कई सेकंड का CPU समय खा सकती है
- उदाहरण के लिए, React और उसकी dependencies को install करते समय npm लगभग 10 लाख, yarn 40 लाख, pnpm 5 लाख, और bun 1.6 लाख system calls का उपयोग करता है
मौजूदा पैकेज मैनेजर और Bun के दृष्टिकोण में अंतर
- npm, pnpm, और yarn सभी Node.js आधारित हैं, जहाँ JavaScript को कई abstraction layers (libuv, event loop, thread pool, system call mediation) के ज़रिए चलाना पड़ता है
- इस दौरान argument conversion, worker pool queue, event loop task branching, और futex (lock synchronization) system calls जैसी चीज़ें जुड़ती जाती हैं, जिससे IO से ज़्यादा system call management ही धीमा पड़ जाता है
- Node.js में बने पैकेज मैनेजर इस संरचनात्मक सीमा के कारण वास्तविक native-जैसा प्रदर्शन हासिल करना मुश्किल पाते हैं
Bun: Zig में बना native install engine
- Bun Zig भाषा में सीधे system calls को invoke करता है, इसलिए JavaScript engine और abstraction layers पूरी तरह हट जाती हैं
- उदाहरण के लिए file read करने के लिए Zig code सीधे
openat() system call चलाता है और तुरंत data लौटा देता है
- इसलिए दसियों हज़ार files पढ़ने की प्रक्रिया किसी अलग thread pool, event loop, या data conversion के बिना बहुत तेज़ चलती है
- benchmark में Bun प्रति सेकंड 146,057
package.json files पढ़ सकता है, जबकि Node.js लगभग 60,000 के स्तर पर है, यानी 2 गुना से अधिक धीमा
Dependency management और DNS optimization
- Bun,
bun install चलाते समय dependency analysis के साथ-साथ DNS prefetch को asynchronous रूप से trigger करता है
- उदाहरण के लिए macOS पर यह Apple की non-official async DNS API (
getaddrinfo_async_start()) का उपयोग करता है, जिससे thread blocking के बिना network tasks को साथ-साथ चलाया जा सकता है
- मौजूदा पैकेज मैनेजर libuv thread pool पर निर्भर रहते हैं, जहाँ अंदर से वास्तव में blocking code चलता है और resources बर्बाद होते हैं
Package manifest binary caching
- npm आदि manifest को JSON के रूप में cache करते हैं, लेकिन Bun एक बार parse करने के बाद उसी परिणाम को binary (
.npm file) में बदलकर स्टोर करता है
- string duplication और parsing overhead कम होता है, और memory में offset calculation के ज़रिए सीधे values तक पहुँचा जा सकता है, इसलिए नए objects बनाने, parsing, या garbage collection की ज़रूरत नहीं पड़ती
- ETag और If-None-Match headers से सिर्फ़ बदलाव की जाँच की जाती है, जिससे अनावश्यक data parsing के बिना freshness verify की जा सकती है
- benchmark में Bun का cached install, npm के fresh install से भी तेज़ है
Tarball (compressed file) processing performance
- सामान्य पैकेज मैनेजर tarball को stream के रूप में लेते हैं, और buffer memory कम पड़ने पर बार-बार reallocation, copy, और resize होता रहता है
- Bun पूरा tarball receive करने के बाद उसे unpack करता है, और gzip के आख़िरी 4 bytes से uncompressed size पहले से पता कर लेता है, इसलिए सिर्फ़ एक बार memory allocate करनी पड़ती है
libdeflate आदि का उपयोग करके extraction तेज़ की जाती है, और अनावश्यक duplicate copy तथा size resize दोनों हटा दिए जाते हैं
Dependency graph और data structure optimization
- पारंपरिक पैकेज मैनेजर JavaScript objects और pointers पर आधारित dependency tree बनाते हैं, जिससे memory random रूप से बिखरती है और CPU cache misses बार-बार होते हैं (pointer chasing समस्या)
- Bun Structure of Arrays (SoA) pattern अपनाता है, जिसमें सभी packages, strings, और dependencies को बड़े लगातार memory blocks में रखा जाता है
- offset/length आधारित access से CPU एक बार में कई packages को cache line स्तर पर पढ़ सकता है, यानी यह एक cache-friendly संरचना है
- lockfile को भी JSON/YAML के बजाय SoA pattern के अनुकूल रखा जाता है, ताकि string deduplication और sequential memory access आसान हो
- lockfile का binary format (
bun.lockb) प्रयोगात्मक रूप से लाया गया था, लेकिन Git सहयोग में कमी आने के कारण इसे अधिक readable plain format में बदल दिया गया
OS-विशिष्ट file copy optimization
macOS
clonefile का उपयोग: पूरे directory को Copy-On-Write तरीके से एक ही system call में clone किया जाता है
- इससे disk space duplication कम होती है और install speed अधिकतम हो जाती है
clonefile विफल होने पर fallback के रूप में per-directory cloning और फिर copyfile तक क्रमिक fallback किया जाता है
Linux
- पहले hardlink का प्रयास: नई file बनाए बिना मौजूदा file के लिए सिर्फ़ नया reference बनाया जाता है, इसलिए disk data move नहीं होता
- hardlink संभव न हो तो Btrfs/XFS पर
ioctl_ficlone के जरिए Copy-On-Write लागू किया जाता है
- इसके बाद
copy_file_range, sendfile, और अंत में सामान्य copyfile तरीके तक fallback किया जाता है
कुल मिलाकर
- Bun ने system calls को कम करके, binary structures, OS optimization, और data structure सुधार के ज़रिए पैकेज मैनेजर की पारंपरिक performance सीमाओं को पार किया है
- इससे ultra-fast install के साथ-साथ memory और CPU efficiency भी बेहतर होती है
- मौजूदा Node.js आधारित मैनेजरों की तुलना में इसे project में बिना runtime बदले भी लागू किया जा सकता है, यानी compatibility बनी रहती है
- यह बड़े codebase में कई मिनट लेने वाली install प्रक्रिया को milliseconds से लेकर कुछ seconds के भीतर लाने का अनुभव देता है
- system, hardware, और OS स्तर के हिसाब से की गई इस तरह की optimization अध्ययन और संदर्भ के लिहाज़ से बहुत मूल्यवान है
अभी कोई टिप्पणी नहीं है.