1 पॉइंट द्वारा GN⁺ 2025-03-19 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • उसी jq सोर्स को दोबारा बिल्ड करके allocator बदलने पर, 500MB GeoJSON प्रोसेसिंग समय 4.606 सेकंड से 2.428 सेकंड तक घट गया, जिससे यह Ubuntu बाइनरी से 1.90 गुना तेज़ हो गया
  • बेंचमार्क Ryzen 9 9950X पर Alameda County Assessor parcel map के लिए TotalNetValue < 193000 शर्त के SitusCity निकालने के तरीके से किया गया
  • सिर्फ साधारण rebuild से भी 2~4% सुधार मिला, और clang-18, -O3, -flto, -DNDEBUG संयोजन ने Ubuntu पैकेज की तुलना में 1.20 गुना प्रदर्शन दिया
  • प्रोफाइल में मेमोरी allocation लागत काफी बड़ी दिखी, इसलिए TCMalloc, jemalloc, mimalloc की तुलना की गई; LD_PRELOAD प्रयोग में mimalloc सबसे तेज़ रहा
  • अंतिम mimalloc लिंक्ड बिल्ड ने अलग 2.2GB JSON प्रोसेसिंग मामले में भी 0.755 सेकंड बनाम 1.424 सेकंड दर्ज किया, जिससे पता चलता है कि workload के अनुसार distro के डिफ़ॉल्ट बिल्ड से बड़ा अंतर आ सकता है

आधारभूत workload और मापने का तरीका

  • टेस्ट का लक्ष्य JSON प्रोसेसिंग टूल jq है, और इनपुट डेटा Alameda County Assessor के parcel map वाला 500MB GeoJSON फ़ाइल है
  • चलाया गया query parcel सूची में TotalNetValue < 193000 शर्त पूरी करने वाले आइटमों का SitusCity आउटपुट करता है
    • .features[] | select(.properties.TotalNetValue < 193000) | .properties.SitusCity
  • Ubuntu का डिफ़ॉल्ट /usr/bin/jq फ़ाइल cache में होने पर लगभग 5 सेकंड लेता था, और विस्तृत बेंचमार्क hyperfine से बार-बार मापा गया
  • रन के दौरान बदलाव कम करने के लिए taskset -c 2 से इसे logical CPU 2 पर pin किया गया
    • यह सेटिंग CPU 0 पर चलने वाले system interrupt और CPU migration के असर से बचने के लिए थी

उसी सोर्स का साधारण rebuild

  • Ubuntu द्वारा उपयोग किए गए jq source code को लेकर बिना किसी अलग flag के configure और build किया गया
  • सिर्फ इस साधारण rebuild से भी Ubuntu बाइनरी पैकेज की तुलना में लगभग 2~4% अधिक गति मिली
    • rebuilt बाइनरी: औसत 4.517 सेकंड
    • Ubuntu /usr/bin/jq: औसत 4.641 सेकंड
    • नतीजतन लगभग 1.03 गुना प्रदर्शन मिला

clang और optimization flags का उपयोग

  • अगले चरण में clang-18, ऊँचा optimization level, LTO, और debugging/profiling से जुड़े flags को साथ में लागू किया गया
  • प्रदर्शन पर असर डालने वाले मुख्य flags थे -O3, -flto, -DNDEBUG
    • -O3, -O2 से ऊँचा optimization level उपयोग करता है
    • -flto link-time optimization को सक्षम करता है
    • -DNDEBUG प्रोफाइल में बड़े दिखे assertion cost को कम करता है
  • उपयोग किया गया configure उदाहरण इस प्रकार है
    • CC=clang-18
    • LDFLAGS="-flto -g -Wl,--emit-relocs -Wl,-z,now -Wl,--gc-sections -fuse-ld=lld"
    • CFLAGS="-flto -DNDEBUG -fno-omit-frame-pointer -gmlt -march=native -O3 -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections"
  • यह बिल्ड Ubuntu बाइनरी की तुलना में 1.20 गुना तेज़ था
    • optimized rebuild: औसत 3.853 सेकंड
    • Ubuntu /usr/bin/jq: औसत 4.631 सेकंड

allocator बदलने का प्रयोग

  • jq एक जटिल C प्रोग्राम है, और प्रोफाइल में मेमोरी allocation सबसे बड़ा खर्च दिखा
  • पहले Ubuntu पैकेज के रूप में उपलब्ध TCMalloc को लिंक करके फिर से build किया गया
    • LDFLAGS में -L/usr/lib/x86_64-linux-gnu -ltcmalloc_minimal जोड़ा गया
    • rebuilt बाइनरी: औसत 3.253 सेकंड
    • Ubuntu /usr/bin/jq: औसत 4.611 सेकंड
    • यानी Ubuntu बाइनरी की तुलना में 1.42 गुना तेज़ परिणाम मिला
  • डिफ़ॉल्ट Ubuntu बाइनरी में सिर्फ LD_PRELOAD से allocator बदलने पर भी कुछ सुधार संभव था
    • डिफ़ॉल्ट: औसत 4.601 सेकंड
    • TCMalloc preload: औसत 4.082 सेकंड
    • डिफ़ॉल्ट की तुलना में 1.13 गुना तेज़

dynamic preload और THP सेटिंग

  • Ubuntu द्वारा उपलब्ध jemalloc, mimalloc, TCMalloc को LD_PRELOAD के साथ तुलना की गई
  • यह तुलना नीचे दिए गए environment variables सेट करने के बाद मिले परिणामों पर आधारित है
    • MIMALLOC_LARGE_OS_PAGES=1
    • MALLOC_CONF="thp:always,metadata_thp:always"
    • GLIBC_TUNABLES=glibc.malloc.hugetlb=1
  • नतीजतन mimalloc सबसे तेज़ निकला
    • डिफ़ॉल्ट glibc: औसत 4.123 सेकंड
    • TCMalloc preload: औसत 4.130 सेकंड
    • jemalloc preload: औसत 3.510 सेकंड
    • mimalloc preload: औसत 3.154 सेकंड
  • THP सक्षम करने से glibc allocator, jemalloc, और mimalloc तीनों को फायदा मिला
  • THP + mimalloc, THP + glibc से 31% तेज़ था, और glibc डिफ़ॉल्ट से 48% तेज़ था

mimalloc लिंक्ड बिल्ड का अंतिम परिणाम

  • dynamic preload को प्रदर्शन के लिहाज़ से आदर्श नहीं माना गया, इसलिए अंतिम चरण में mimalloc को लिंक करके jq को फिर से build किया गया
  • अंतिम बिल्ड Ubuntu बाइनरी पैकेज की तुलना में 1.90 गुना तेज़ था
    • mimalloc rebuilt: औसत 2.428 सेकंड
    • Ubuntu /usr/bin/jq: औसत 4.606 सेकंड
    • हर बेंचमार्क 10 रन के आधार पर था
  • वही बिल्ड दूसरे application में भी उपयोग किया गया
    • 2.2GB JSON को 13,000 फ़ाइलों में प्रोसेस किया गया
    • parallelization के लिए rush का उपयोग हुआ
    • mimalloc rebuilt jq: 0.755 सेकंड
    • Ubuntu पैकेज jq: 1.424 सेकंड
  • इस अलग मामले में भी गति सुधार लगभग 2 गुना के करीब था

1 टिप्पणियां

 
GN⁺ 2025-03-19
Hacker News की राय
  • “एक Ubuntu पैकेज को फिर से build करके और memory allocator बदलकर 90% तेज़ बनाना” जैसे clickbait पर तो TCP/IP के उस पार जाकर एक थप्पड़ मारने का मन करता है। यह सिर्फ़ एक पैकेज था, और कुछ सुधार recompile की वजह से भी नहीं थे
    फिर भी मैंने jemalloc को LD_PRELOAD के ज़रिए एक program में लगाकर malloc implementation बदलकर देखा था, और नतीजे काफ़ी अच्छे थे। performance मापी नहीं थी, लेकिन उस application की memory usage stable हो गई और memory leak जैसा दिखने वाला issue भी हल हो गया। असल में यह app की अपनी समस्या कम और standard malloc की memory fragmentation होने की संभावना ज़्यादा थी

    • मैंने glibc memory allocator की जांच की थी, और यह memory fragmentation नहीं बल्कि per-thread cache की वजह से था, जो kernel को कभी वापस नहीं लौटता। free() call करने पर भी, असाधारण स्थितियों को छोड़कर, बाहर से memory सच में release नहीं होती
      threads और CPU cores जितने ज़्यादा होते हैं, यह समस्या उतनी बढ़ती है। एक आसान समाधान “magic” environment variable MALLOC_ARENA_MAX=2 set करके caches की संख्या limit करना है। दूसरा तरीका यह है कि application नियमित रूप से malloc_trim() call करके cache खाली करे, लेकिन इसके लिए source में बदलाव चाहिए
      https://www.joyfulbikeshedding.com/blog/2019-03-14-what-caus...
    • सही है, मैं भी थोड़ी देर के लिए भरोसा करने ही वाला था। लेकिन Ubuntu को गलती का कारण ठहराना भी आसान है। निजी तौर पर मुझे लगता है Ubuntu packages को assemble करने का काम काफ़ी अच्छा करता है, और सच में stack protection options भी enable करके compile करता है
      उल्टा, संभावित रूप से bugs ला सकने वाले -O3 से compile नहीं करना अच्छी बात है। performance-critical कुछ हिस्सों के लिए यह अच्छा हो सकता है, लेकिन पूरे system को -O3 से compile करना मैं नहीं चाहूंगा
    • इतने बड़े स्तर का ऐसा improvement सिर्फ़ एक लेख की explanation से हासिल हो सकता है, यह संभव नहीं लगता, इसलिए साफ़ तौर पर बढ़ा-चढ़ाकर कहा गया लगता है। 90% तेज़ एक microbenchmark number है
    • सोचता हूं कि pre-packaged binary distributions में से कितनी operating system और hardware के लिए सबसे safe options के साथ build होती हैं और best possible performance नहीं दे पातीं। ईमानदारी से कहूं तो शायद ज़्यादातर
      बहुत पहले मैंने Mozilla और अपने Linux kernel को अपनी पसंद के हिसाब से build करना शुरू किया था, और आम तौर पर ठीक-ठाक performance improvement मिलता था। Gentoo Linux distribution का पूरा मकसद भी, उदाहरण के लिए, हर चीज़ को source से optimized compile करके performance gain पाना ही है
    • title clickbait है, लेकिन app developers को फिर से build करके देखने के लिए encourage करना अच्छा है। खासकर जब jq, grep, ffmpeg, ocrmypdf जैसी कुछ common utilities में CPU bottleneck हो, और ऐसी general Unix utilities अक्सर किसी specific application के बजाय general-purpose build target के तौर पर बनाई जाती हैं
  • Engineering समझौता है। लेख में ज़्यादातर फ़ायदा memory allocator को specialize करने से आया। यह याद रखना चाहिए कि कुछ projects multi-threaded होते हैं, एक thread में allocation करते हैं, दूसरे thread में data लिखते हैं और तीसरे thread में free भी कर देते हैं।
    allocator को यह सब handle करना पड़ता है, इसलिए एक project की speed boost दूसरे project में crash बन सकती है। reallocation strategy भी समस्या है। कुछ programs पहले से allocate कर लेते हैं और फिर कभी malloc को नहीं छूते, लेकिन दूसरे programs लगातार free करके फिर से लेते रहते हैं। fragmentation को कितनी अच्छी तरह handle किया जाता है, uptime 10 सेकंड है या 10 साल—यह भी मायने रखता है। कभी-कभी allocator का चुनाव long-term stability और short-term speed के बीच का फर्क बन जाता है।
    4K video test करते हुए frames cache करने वाला video editor बनाते समय मैंने कई allocators आज़माए थे। 32MB per frame, 60fps पर एक track के लिए लगभग 2GB प्रति सेकंड होता है। तुरंत allocator की limits से टकरा जाते हैं, और समझ आता है कि कम से कम default glibc allocator long-term stability के लिए सबसे अच्छा है। लेकिन छोटे benchmarks में वही सबसे धीमा होता है।

    • Mimalloc, JEMalloc / TCMalloc जैसा general-purpose allocator है। glibc को काफ़ी खराब allocator माना जाता है, और MIMalloc या modern TCMalloc, यानी Ubuntu में default मिलने वाला version नहीं, glibc से काफ़ी आगे हैं।
      बेशक speed improvement की मात्रा अलग-अलग हो सकती है, लेकिन benchmarks आम तौर पर overall improvement दिखाते हैं। यह किसी specific application के लिए meaningful है या नहीं, यह बिल्कुल अलग मुद्दा है। crashes के बारे में भी, ये सभी general-purpose multi-threaded allocators हैं, इसलिए glibc से अलग व्यवहार नहीं करते, और bugs glibc में भी उतने ही हो सकते हैं।
    • मैं भी बड़े 8K video frames handle करता हूँ [1]। अगर बात खुद frames की है, तो प्रति सेकंड 60 allocations कुछ भी नहीं हैं। glibc धीमा होने की सिर्फ एक वजह है। हर allocation DEFAULT_MMAP_THRESHOLD_MAX से ऊपर चला जाता है, और 64-bit platforms पर यह 32MiB है, इसलिए mallopt manual में documented तरीके से glibc को इसे cache करने के लिए राज़ी नहीं किया जा सकता।
      हर बार mmap से सीधे kernel से memory मांगी जाती है और munmap से वापस की जाती है। ये system calls थोड़े slow हैं, और मेरे मामले में पहली access पर हर memory page पर page fault कराने की cost performance target पूरा न कर पाने जितनी धीमी है। solution सचमुच simple है। सिर्फ video frames के लिए general-purpose allocator या mmap के ऊपर अपनी free list इस्तेमाल कर लें। बिल्कुल same size की allocations बहुत reliably repeat होती हैं, इसलिए यह अच्छी तरह काम करता है।
      [1] UYVY format में 64MiB से थोड़ा कम, और I420 format में 48MiB से थोड़ा कम।
    • यह comment समझना थोड़ा मुश्किल है। मुझे C या C compiler की बहुत जानकारी नहीं है, लेकिन पूरा gist पढ़कर बहुत कुछ सीखा और वह valuable लगा।
      लेकिन यह parent comment पढ़कर चिंता हो रही है कि कहीं मैंने लेख को पूरी तरह गलत तो नहीं समझ लिया। tone से ऐसा लगता है जैसे gist में कही बात बिल्कुल नहीं करनी चाहिए, और यह ऐसी भयानक सलाह है जिसने इन सारी complexities को नज़रअंदाज़ कर दिया है। क्या आप समझने में मदद कर सकते हैं कि original gist अच्छा लेख है या नहीं, उसमें valid points हैं या नहीं, या उसकी कोई value ही नहीं है? यह comment देखने से पहले मुझे वह valuable लगा था, लेकिन अब एहसास हुआ कि शायद मैं फर्क समझने लायक smart नहीं हूँ।
    • इसलिए दुनिया की हर चीज़ के लिए एक ही allocator इस्तेमाल करना खराब idea है। single-threaded applications, बल्कि resource management को सख्ती से संभालने वाली multi-threaded applications तक, सभी से thread safety की cost वसूलना भयानक है।
    • यह आम दर्द है। project के हिसाब से सही language इस्तेमाल करो, तो लोग किसी-न-किसी वजह से कहते हैं कि तुम्हें दूसरी language इस्तेमाल करनी चाहिए थी।
      data के हिसाब से सही compression algorithm इस्तेमाल करो, तो लोग बताते हैं कि तुम बेवकूफ क्यों हो और तुम्हें दूसरा algorithm इस्तेमाल करना चाहिए था। हाल ही में Dynamo में डालने के लिए एक specific लंबी JSON string compress करनी थी, और सभी popular algorithms को thoroughly test किया तो Brotli बहुत आगे निकला। फिर भी इससे हर राह चलते व्यक्ति को यह कहने से नहीं रोका जा सका कि zlib बेहतर है। कभी-कभी काफ़ी थका देने वाला होता है।
  • Gentoo Linux असल में ऐसे ही लोगों के लिए बनी distro है, ताकि वे अपनी Linux मशीन को अपने इस्तेमाल के हिसाब से optimize कर सकें
    शुरुआती setup के बाद यह काफी simple और इस्तेमाल में आसान है। मुझे याद है कि Matrix के Gentoo Linux channel में मैंने कई दोस्त बनाए थे; मज़ेदार दिन थे
    https://www.gentoo.org/
    एक दिलचस्प बात: शुरुआती ChromeOS मूल रूप से custom Gentoo Linux install ही था। पता नहीं अब भी अंदरूनी तौर पर Gentoo Linux इस्तेमाल करता है या नहीं

    • सही है, लेकिन यहाँ optimization का मतलब ज़रूरी नहीं कि performance ही हो—यह बात कहना ठीक रहेगा
      मैंने Gentoo 20 साल इस्तेमाल किया है, लेकिन performance की वजह से कभी नहीं। जब आपको पता हो कि आप system से कैसा व्यवहार चाहते हैं, तो Gentoo शानदार है और वहाँ तक पहुँचने में मदद करता है
    • HN वाला “install gentoo” meme पहली बार देखा। वाकई ज्यादा refined है
      Gentoo का लक्ष्य ऐसा operating system रखना है जिसमें pre-built binary packages के बजाय सभी programs source से build होते हैं। इससे advanced speed improvements और customization संभव होता है, लेकिन इसका मतलब यह भी है कि kernel जैसे सबसे basic components भी source से compile करने पड़ते हैं। Linux community में यह अपने भारी-भरकम installation process की वजह से बहुत complex operating system माना जाता है। एक basic Gentoo installation सीधे command prompt में boot होता है, और user को खुद disk partition करने, “Stage 3 tarball” नाम का package download करके extract करने, packages manually install करने और system बनाने की जरूरत होती है। नए या कम अनुभवी users अक्सर installer में जाने पर graphical screen न दिखे तो समझ नहीं पाते कि क्या करें। /g/ members अक्सर Gentoo की value बढ़ा-चढ़ाकर बताते हैं ताकि नए users को install करने की कोशिश में फँसा सकें
    • 2003 से लगातार Gentoo इस्तेमाल कर रहा था, फिर बिल्कुल हाल ही में 2024 के अंत में Void Linux try करते हुए उस पर shift हो गया। Void में end users का source से build कर पाना कोई घोषित लक्ष्य या architecture feature नहीं है, लेकिन इसे सच में काम करा लेने की संभावना काफी ज्यादा है
      एक-दो बार अटक सकता है, लेकिन अगर आपका overall Linux experience पर्याप्त है, तो build recipe में जाकर उसे ठीक करने, अपनी जरूरत के हिसाब से चलाने और fixes upstream contribute करने की संभावना ज्यादा है। यह minimalism पर जबरदस्त focus और किसी भी तरह की overengineering से बचने का परिणाम है। Gentoo इस्तेमाल करते हुए मुझे यही हिस्सा हमेशा खलता था। Gentoo में मैं हमेशा USE flags और package masks को ऐसे तरीकों से छेड़ता रहता था जो दूसरे users के लिए खास मददगार नहीं होते। Build system इतना complex था कि लंबे समय तक उसे सही से सीखना, root-cause level पर issues fix करना और upstream contribute करना बहुत मुश्किल था। अगर आप पूरा system source से build नहीं करना चाहते, लेकिन distro-provided binaries और खुद source से build किए packages को मिलाकर इस्तेमाल करना चाहते हैं, तो Void एक ideal base हो सकता है
    • मैंने Gentoo कुछ समय तक इस्तेमाल किया, लेकिन हर चीज़ को endlessly tweak करने के temptation की वजह से आखिरकार system खराब कर देता था। Gentoo की गलती नहीं, मेरी गलती थी
      इसके बाद ArchLinux पर चला गया, और मेरे लिए वह कुल मिलाकर ठीक रहा। अगर आप काफी standard processor इस्तेमाल कर रहे हैं, तो मुझे नहीं लगता Gentoo इतना बड़ा फायदा देगा
    • मेरी जानकारी में Gentoo-based ChromeOS को Android से replace किया जा रहा है
  • ऐसा करने पर आप सिर्फ jq ही नहीं, बल्कि regex parsing dependency onigurama के security updates से भी बाहर हो जाएंगे। पहले onigurama security update आया था, और अगर ऐसा फिर हुआ तो आप vulnerable हो सकते हैं। jq अक्सर untrusted JSON parse करने के लिए इस्तेमाल होता है
    उसमें लिखा था, “security update: multiple invalid pointer dereferences, out-of-bounds write memory corruption, stack buffer overflow fixes”, और वह CVE-2017-9224, CVE-2017-9226, CVE-2017-9227, CVE-2017-9228, CVE-2017-9229 के लिए था

    • Gentoo Prefix जैसे user-space package manager का इस्तेमाल करें तो यह custom build install करते हुए भी security updates मिलते रह सकते हैं
    • फिर भी platform के हिसाब से intelligently decide करने वाले package management system का seed idea तो है, नहीं? छोड़ देने के लिए performance काफी बड़ी लगती है
    • आम तौर पर यह सही है, लेकिन इस case में गलत है। gist में बताया गया build अब भी onigurama को dynamically link कर रहा है। onigurama libonig5 नाम के अलग package में है, और वह normal तरीके से update होगा
    • सोचता हूँ ऐसे CVE आम तौर पर कितने applicable होते हैं। यह कहने जैसा लगता है कि घर के अंदर के दरवाजे इस्तेमाल करने से vault door वाली security नहीं मिलती। बात गलत नहीं है, लेकिन banks के हर दरवाजे vault door न होने की भी वजह होती है
      CVE system की value कम करके नहीं आँकना चाहता, लेकिन findings के बीच real-world impact में बड़ा फर्क होता है, यह भी नकारना मुश्किल है
    • बिल्कुल सही। और allocator बदलने व compiler flags बदलने से, किसी खास memory layout पर निर्भर attacks से आप संयोग से immune भी हो सकते हैं
  • इस तरह की चीज़ों से निपटे हुए मुझे कुछ समय हो गया है, लेकिन मेरी याद में upstream developers जो flags इस्तेमाल करते हैं, उनसे आगे जाते ही अजीब bugs और bug आने पर जबरदस्त उदासीनता मिलती है। यहाँ मेरा मतलब distro packager से नहीं, upstream developer से है
    libc के अलावा malloc मैंने कभी इस्तेमाल नहीं किया, लेकिन वही principle लागू होगा लगता है

    • दो विपरीत बातें एक साथ सही हैं। अगर कोई व्यक्ति जरा भी अलग न होने की कोशिश करे, तो वह सबसे ज्यादा लोगों वाले रास्ते पर है और short term में उसकी success की संभावना सबसे ज्यादा है
      लेकिन अगर सब ऐसा करें तो वह monoculture बन जाता है, और monoculture fragile और खराब होता है। Code तभी थोड़ा मजबूत बनता है जब वह अलग contexts—यानी अलग platforms, compilers, options, libraries वगैरह—में build होता है। कोई bug जिसे ज्यादातर लोगों ने इसलिए नहीं छुआ क्योंकि उनका platform या build flags संयोग से trap के ठीक बगल से निकल गए, फिर भी bug ही है; उसे ढूँढना और fix करना code के लिए बेहतर है। Individuals के तौर पर हम सबको फायदा होता है जब code कुल मिलाकर fragile होने के बजाय robust बनता है
    • मैं लंबे समय से अपना emacs खुद build करता आया हूँ, और अब तक कोई अजीब bug नहीं मिला। मुझे लगता था कि unsafe optimizations से बचें तो ठीक है
      बेशक, मैं यह भी सोचता था कि -march=native ही मुझे दिखने वाला मुख्य improvement है, लेकिन यह article दिखाता है कि जरूरी नहीं ऐसा ही हो। Floating-point इस्तेमाल करने वाली applications में rough edges ज्यादा होने की संभावना भी लगती है
    • उल्टा, अगर optimization कई platforms पर consistently मदद करता है, तो upstream developer को इसे खुद implement करने के लिए मनाया जा सकता है। जरूरी नहीं कि सभी platforms पर हो; अगर किसी single architecture पर performance gain पर्याप्त बड़ा है, तो उस build की settings adjust करने की वजह बन सकता है
  • यह कुछ हद तक किसी खास workflow में benchmark अच्छे दिखाने वाले दूसरे allocator के साथ फिर से build करने जैसा है

    • glibc malloc से बेहतर तो लगभग कुछ भी हो सकता है। distros का mimalloc या jemalloc के बजाय लगातार glibc malloc इस्तेमाल करना असल में कर्तव्य में चूक जैसा है
    • क्या यह भी पता है कि glibc malloc किस तरह के workloads के लिए अच्छा है?
  • उत्सुकता है कि performance की तुलना इस Rust-आधारित jq clone से कैसी होगी
    cargo install --locked jaq
    किसी खास CPU family के लिए optimization चालू करना हो तो RUSTFLAGS="-C target-cpu=native" भी जोड़ सकते हैं। cargo install Rust का एक underrated feature है, जो लेख में बताए गए तरह के use case के लिए बिल्कुल फिट बैठता है। यह tool को source से build करता है, इसलिए आप platform-specific features या instructions चुन सकते हैं जो पुराने CPUs के साथ compatibility के लिए आम तौर पर binaries में शामिल नहीं किए जाते। repository clone करने या build करने का तरीका पता लगाने की जरूरत भी नहीं होती, वह सब अपने आप साथ आ जाता है
    jaq[1] और yq[2] वे विकल्प हैं जिन्हें मैं jq इस्तेमाल करते समय जब भी तेज और आसान performance boost चाहिए होता है, चुनता हूँ
    [1] https://github.com/01mf02/jaq
    [2] https://github.com/mikefarah/yq

    • मैं कभी-कभी jaq की तुलना jq, gojq से करता हूँ, और AoC 2022 day 13 के लिए अपने jq solution से test करता हूँ
      https://gist.github.com/oguz-ismail/8d0957dfeecc4f816ffee79d...
      यह अभी भी दोनों से पीछे है
    • bonus के तौर पर, जो शायद लोगों को न पता हो: जब आप सीधे repository इस्तेमाल करना चाहें, तो cargo install में repository URL specify करने के लिए --git flag भी है। इसका इस्तेमाल तब हो सकता है जब कोई public package न हो या आप latest commit चाहते हों जो अभी release नहीं हुआ है
      मैंने पहले भी इसे कई बार इस्तेमाल किया है, खासकर अपने लिए जल्दबाजी में बनाए गए tool को repository में push करने के बाद उसे जल्दी install करने के आसान तरीके के रूप में—बिना release process बनाने, binaries को अपनी निजी machines पर manually copy करने, या build में इस्तेमाल हुए exact commit को track करने की जरूरत के
  • अगर वाकई ऐसा करना है, तो Ubuntu से वही source package download करवाना चाहिए जो वह चाहता है। इस case में apt-get source jq इस्तेमाल करें
    फिर package के अंदर जाकर मनचाहे तरीके से फिर से compile कर सकते हैं। distribution या archival के लिए उसे फिर से package भी कर सकते हैं। ऐसा करने से अजीब errors और mismatches का ढेर मिलने के बजाय, आपको upstream Ubuntu के काफी ज्यादा करीब result मिलेगा

  • title misleading है। मतलब तेज हुए time का 90% है, और असल में यह करीब 45% तेज है
    अगर आपको इस बात में दिलचस्पी है कि हम भाषा का इस्तेमाल कैसे करते हैं, तो यह थोड़ा रोचक है। आप कह सकते हैं कि उसी समय में 90% ज्यादा काम होता है, और यह उन दूसरी speed units से मेल खाता है जिन्हें हम आम तौर पर इस्तेमाल करते हैं, जैसे miles per hour, words per minute, bits per second। लेकिन computer performance में convention यह है कि fixed amount of work में लगने वाले time को measure किया जाता है। शायद इसलिए कि आम तौर पर workload fixed होता है और बदलती है तो इंतजार की अवधि। इस blog post के मामले में भी ठीक यही है, इसलिए time को numerator में रखा जाता है। लेख खुद बहुत दिलचस्प और अच्छी तरह लिखा गया है, लेकिन यह 90% faster नहीं है

    • और ज्यादा misleading यह nuance है कि सभी packages को 90% faster बनाया जा सकता है। यह तो एक specific package है
    • यहाँ time unit के बजाय throughput unit के रूप में “90% faster” इस्तेमाल करना ज्यादा सही लगता है
      ऊपर से अगर time unit इस्तेमाल करनी हो, तो “faster” शब्द इस्तेमाल नहीं किया जाएगा। “45% less time” और “45% faster” बहुत अलग claims हैं, और दोनों programming के अंदर और बाहर मायने रखते हैं
    • संबंधित लेख: https://randomascii.wordpress.com/2018/02/04/what-we-talk-ab...
    • और सोचने पर समझ आया कि यह misleading क्यों है। क्योंकि बड़े value में हुए change को छोटे value के percentage के रूप में बताया जा रहा है
      जब हम कहते हैं “किसी चीज को N% घटाया”, तो आम तौर पर माना जाता है कि वह N% उसी चीज का है जिसे घटाया गया है, किसी दूसरे value का नहीं
    • लगता है सही है। आप कह सकते हैं कि package, यानी code, 45% faster है, या parsing throughput को 90% बढ़ाता है। लेकिन दोनों को मिलाने से confusion होता है
  • यह पढ़कर कि इतने simple change से बड़ा speedup मिल सकता है, मेरे मन में सबसे पहले यही आया कि jq authors को बताना चाहिए। इसमें सावधान रहने लायक pitfalls हो सकते हैं, या test करने के बाद वे इसे सभी के लिए faster बना सकते हैं
    नतीजा चाहे जो हो, बस inform कर देना useful लगता है। लेकिन लेख में यह option consider तक किया हुआ नहीं लगता, और यहाँ comments में भी दिखाई नहीं देता। क्या मैं कुछ miss कर रहा हूँ?

    • उत्सुकता है कि Intel Clear Linux instruction set के ज्यादा नए operation codes इस्तेमाल करके इसी तरह का लाभ पाता है या नहीं
      पता नहीं वहाँ भी glibc allocator standard है या नहीं
      https://en.m.wikipedia.org/wiki/Clear_Linux_OS