„Bun“ ar „Node.js“: penkiskart greitesnis startas slepia API spragas

|Autorius: QUASA redakcija|5 min. skaitymo
„Bun“ ar „Node.js“: penkiskart greitesnis startas slepia API spragas

2026 m. rugpjūčio 28 d. „Apple M4“ baziniame bandyme „Bun“ šaltasis paleidimas truko 5,2 ms, o „Node.js“ – 26,0 ms; neveikos atmintis siekė atitinkamai 12,3 ir 48,2 MiB. „Bun“ greičiau atliko penkias iš šešių skaičiavimo užduočių, tačiau „nbody“ užduotyje buvo maždaug 20 proc. lėtesnis. Tai konkretaus kompiuterio, vykdymo aplinkų versijų ir bandymo užduočių rezultatai, o ne pažadas tokį pat skirtumą gauti bet kurioje programoje.

Trumpalaikiam procesui ar dažnai paleidžiamam CLI įrankiui „Bun“ yra rimtas kandidatas pakeisti „Node.js“. Nuolat veikiančiame serveryje sprendimą pirmiausia lemia naudojamų API elgsena, užklausų delsa ir atmintis esant tikrajai apkrovai. Vien tuščio scenarijaus paleidimas neparodo, ar programa teisingai apdoros ryšius, perduos asinchroninį kontekstą ir valdys antrinius procesus.

Kada šaltasis paleidimas iš tiesų svarbus

„Apple M4“ bandyme „Bun“ paleidimas trunka 5,2 ms, o „Node.js“ – 26,0 ms.

Paleidimo skirtumas kaupiasi tada, kai procesas sukuriamas kiekvienai komandai ar atskirai užduočiai. Tokiam darbui verta matuoti visą kelią nuo komandos iškvietimo iki naudingo rezultato: failų įkėlimą, priklausomybių importą, konfigūracijos nuskaitymą ir pačią užduotį. Jei paleidimas sudaro tik mažą šio kelio dalį, sutrumpėjęs vykdymo aplinkos startas bendrą laukimą pakeis nedaug.

„Bun“ vykdymo aplinkos dokumentacijoje nurodo naudojanti „JavaScriptCore“ ir tiesiogiai vykdanti „TypeScript“ bei JSX failus, kuriuos prieš vykdymą transformuoja. Tai gali sutrumpinti paprasto įrankio paleidimo kelią, jei esamame projekte jam reikia atskiro transformavimo žingsnio. Vis dėlto palyginime turi dalyvauti įprasta programos paleidimo komanda, o ne specialiai bandymui supaprastintas failas.

Ilgai veikiančio serverio starto sąnaudos pasiskirsto per visą jo darbo laiką. Net ir tokiu atveju paleidimas gali būti svarbus, jeigu procesai dažnai keičiami arba automatiškai didinamas jų skaičius. Čia matuotinas laikas iki pasirengimo priimti tikrą užklausą, įskaitant būtinus prisijungimus prie duomenų bazės ir kitų paslaugų.

Ką parodo atmintis neveikos būsenoje

Mažesnis neveikiančio proceso atminties poreikis gali būti naudingas, kai viename kompiuteryje vienu metu laikoma daug atskirų procesų. Tačiau serveriui vien šis dydis neatskleidžia, kiek atminties prireiks kaupiant duomenis, pildant podėlius ar apdorojant užklausų srautą. Reikia lyginti ir ramią būseną, ir didžiausią naudojimą per tą pačią apkrovą.

„Node.js“ proceso atminties dokumentacija aiškina, kad RSS apima visą pagrindinėje atmintyje esantį procesą, įskaitant kodą ir objektus, o kaupo rodikliai apibūdina tik dalį jo atminties. Todėl abiejų vykdymo aplinkų atmintį prasminga matuoti tuo pačiu operacinės sistemos būdu. Vienos aplinkos kaupo dydžio lyginimas su kitos aplinkos RSS sukurtų klaidingą pranašumą.

Atminties bandyme svarbu išlaikyti tokį pat įvesties duomenų kiekį ir tokį pat vienu metu apdorojamų užklausų skaičių. Taip matyti, ar mažesnė pradinė sąnauda išlieka naudinga veikiant programai. Jei procesai paleidžiami trumpam, verta fiksuoti ir jų didžiausią atminties naudojimą, nes vien neveikos matavimo tokiame darbe gali apskritai nebūti.

Skaičiavimo užduotys turi savo išimtį

Bazinio bandymo rezultatai rodo, kad vieno visiems skaičiavimams tinkamo greičio santykio nėra. Atminties skyrimas, JSON apdorojimas, rikiavimas ir darbas su eilutėmis apkrauna skirtingas vykdymo aplinkos dalis. „Nbody“ išimtis ypač aktuali programai, kurios darbe daug slankiojo kablelio aritmetikos ir pasikartojančio objektų savybių skaitymo.

Skaičiavimo darbui palyginti geriau tinka pačios programos transformacija su tuo pačiu įvesties rinkiniu. Pirmiausia reikia patikrinti rezultato teisingumą, tada matuoti vykdymo laiką ir didžiausią atminties naudojimą. Programai, kuri daugiausia laukia tinklo ar duomenų bazės atsakymo, aritmetinio mikrobandymo rezultatas apie naudotojo patiriamą užklausos delsą pasakys mažai.

Laiko matavimui svarbios vienodos sąlygos: tas pats kompiuteris, vienoda įvestis, tos pačios programos priklausomybės ir pakartotiniai paleidimai. Taip galima atskirti vykdymo aplinkos skirtumą nuo atsitiktinio sistemos apkrovos svyravimo. Trumpalaikiam procesui reikia matuoti visą jo trukmę, o ilgai veikiančiam serveriui – darbą po paleidimo.

Kur stringa „Node.js“ API suderinamumas

„Node.js“ priklausomybių grandinėje išryškėja trijų API modulių suderinamumo spragos „Bun“ aplinkoje.

Importuoti modulį dar nereiškia, kad veiks kiekviena jo funkcija. Oficialioje „Bun“ „Node.js“ suderinamumo lentelėje „node:https“, „node:async_hooks“ ir „node:child_process“ turi konkrečių įgyvendinimo ribų. Jos tampa migracijos kliūtimi tada, kai programa arba jos priklausomybė pasiekia būtent tą funkciją.

  • „node:https“ serverio užklausos lizdas neturi „getPeerCertificate()“ ir „getCipher()“ metodų. Nepalaikomi ir „setSecureContext()“, „addContext()“ bei „SNICallback“. Tai svarbu kodui, kuris tikrina ryšio sertifikatą arba keičia saugaus ryšio kontekstą.
  • „node:async_hooks“ turi „AsyncLocalStorage“ ir „AsyncResource“, tačiau „createHook“ ir kelios asinchroninių operacijų identifikatorių funkcijos yra pakaitalai. „AsyncLocalStorage“ kontekstas taip pat neperduodamas į „MessagePort“, „BroadcastChannel“ ar „Worker“ įvykius. Stebėsenos arba užklausos konteksto biblioteka gali veikti kitaip net tada, kai jos importas pavyksta.
  • „node:child_process“ gali perduoti kai kurių tinklo lizdų deskriptorius, bet negali taip perduoti HTTP serverio lizdo. Išplėstinis serializavimas veikia tik tarp „Bun“ procesų, todėl mišriame „Bun“ ir „Node.js“ procesų ryšyje reikia patikrinti pranešimų formatą.

Šios ribos nėra vienodas verdiktas visoms programoms. Paprastam CLI įrankiui jos gali būti nesvarbios, o serveriui su TLS, stebėsenos agentu ar antriniais procesais – lemiamos. Priklausomybių sąraše reikia žiūrėti ir į netiesiogines bibliotekas: būtent jose gali slėptis kvietimas, kurio pagrindiniame programos kode nematyti.

Migracijos bandymas ir grįžimo sąlygos

Tas pats programos krūvis tikrinamas „Bun“ ir „Node.js“ aplinkose, numatant galimybę grįžti prie „Node.js“.

Bandymo atskaitos taškas turi būti veikianti programa su „Node.js“. Užfiksuokite naudojamas versijas, paleidimo komandą, aplinkos kintamuosius, operacinę sistemą ir apkrovos profilį. Taip tas pats darbas galės būti vykdomas su „Bun“, nekeičiant jo paskirties ar įvesties.

  1. Sudarykite tiesioginių ir netiesioginių priklausomybių inventorių. Pažymėkite TLS ryšius, asinchroninio konteksto perdavimą, antrinių procesų valdymą ir vietas, kur naudojamos konkrečios „Node.js“ funkcijos.
  2. Abiejose aplinkose paleiskite tuos pačius funkcinius ir integracinius testus. Įtraukite kelią, kuris iš tiesų pasiekia jautrią API: vien sėkmingo modulio importo arba serverio paleidimo nepakanka.
  3. Pakartokite tą pačią realiai programai būdingą apkrovą. CLI įrankiui matuokite laiką iki rezultato; serveriui – pasirengimą, užklausų delsą, pralaidumą ir RSS; skaičiavimo darbui – teisingą rezultatą, laiką ir didžiausią atminties naudojimą.

Prieš perkeliant gamybinį procesą verta nusistatyti grįžimo prie „Node.js“ ribas: neveikianti būtina API, neteisingas rezultatas, paslaugai nepriimtina užklausų delsa arba viršyta atminties riba. Tai redakcinė bandymo taisyklė, kurią kiekviena komanda turi susieti su savo paslaugos reikalavimais. Jei „Bun“ pereina šiuos patikrinimus ir pagerina svarbų konkretaus darbo rodiklį, migracija turi pagrindą; vien spartesnis tuščio failo paleidimas tokio pagrindo nesuteikia.

Taip pat skaitykite:

Dalintis:

Prenumeruokite mūsų naujienlaiškį

Gaukite naujausias Web3, DI ir kriptovaliutų naujienas tiesiai į savo el. pašto dėžutę.

0