मुझे आश्चर्य है कि अगर बात शुरू करने से लेकर फाइल करने तक की तुलना में अधिक कुशल कुछ भी करना संभव था। ऐसा प्रतीत होता है कि उत्तर नहीं है। हालाँकि, कुछ सीपीयू (स्काईलेक) zcat | tail
पर सीपीयू पूरी घड़ी की गति तक नहीं चलता है। निचे देखो। एक कस्टम डिकोडर उस समस्या से बच सकता है और पाइप लेखन प्रणाली कॉल को बचा सकता है, और शायद ~ 10% तेज हो। (या यदि आप पावर-मैनेजमेंट सेटिंग्स को ट्वीक नहीं करते हैं तो स्काईलेक पर 60% तेजी से)।
किसी skipbytes
फ़ंक्शन के साथ अनुकूलित ज़्लिब के साथ आप जो सबसे अच्छा कर सकते हैं वह वास्तव में विघटित ब्लॉक को फिर से संगठित करने के काम किए बिना एक संपीड़न ब्लॉक में प्रतीकों को पार्स करने के लिए होगा। यह एक ही बफर को अधिलेखित करने और फ़ाइल में आगे बढ़ने के लिए ज़ालिब के नियमित डिकोड फ़ंक्शन को कॉल करने की तुलना में काफी तेज (शायद कम से कम 2x) हो सकता है। लेकिन मुझे नहीं पता कि किसी ने ऐसा फंक्शन लिखा है या नहीं। (और मुझे लगता है कि यह वास्तव में तब तक काम नहीं करता है जब तक कि फाइल को एक विशेष ब्लॉक में डिकोडर को फिर से शुरू करने की अनुमति देने के लिए विशेष रूप से नहीं लिखा गया था)।
मैं उम्मीद कर रहा था कि डीकोड ब्लॉक के माध्यम से उन्हें डिकोड किए बिना छोड़ने का एक तरीका है, क्योंकि यह बहुत तेज़ होगा। हफ़मैन का पेड़ प्रत्येक ब्लॉक की शुरुआत में भेजा जाता है, इसलिए आप किसी भी ब्लॉक (मुझे लगता है) की शुरुआत से डिकोड कर सकते हैं। ओह, मुझे लगता है कि डिकोडर राज्य हफ़मैन पेड़ से अधिक है, यह डिकोड्ड डेटा के पिछले 32kiB भी है, और यह डिफ़ॉल्ट रूप से ब्लॉक सीमाओं पर रीसेट / भूल नहीं है। एक ही बाइट्स को बार-बार संदर्भित किया जा सकता है, इसलिए केवल एक बार एक विशाल संपीड़ित फ़ाइल में एक बार दिखाई दे सकता है। (उदाहरण के लिए एक लॉग फ़ाइल में, होस्टनाम सम्भवतः सम्पीडन शब्दकोश में "हॉट" रहता है, और इसका प्रत्येक उदाहरण पिछले वाले को संदर्भित करता है, पहले वाले को नहीं)।
zlib
मैनुअल का कहना है कि आप उपयोग करने के लिए है Z_FULL_FLUSH
जब बुला deflate
अगर आप संकुचित धारा है कि बात करने के लिए seekable होना चाहता हूँ। यह "संपीड़न स्थिति को रीसेट करता है", इसलिए मुझे लगता है कि इसके बिना, पीछे के संदर्भ पिछले ब्लॉक (ओं) में जा सकते हैं। इसलिए, जब तक कि आपकी जिप फाइल कभी-कभी पूर्ण-फ्लश ब्लॉक्स के साथ नहीं लिखी जाती (जैसे हर 1G या कुछ का संपीड़न पर नगण्य प्रभाव होगा), मुझे लगता है कि आपको उस बिंदु तक डिकोड करने का काम अधिक करना होगा जो आप शुरू से चाहते हैं। विचारधारा। मुझे लगता है कि आप शायद किसी भी ब्लॉक की शुरुआत में शुरू नहीं कर सकते।
इस के बाकी हिस्सों को लिखा गया था जब मैं सोच रहा था कि यह संभव होगा कि आप पहले बाइट वाले ब्लॉक की शुरुआत का पता लगाएं, और वहां से डिकोड करें।
लेकिन दुर्भाग्य से, एक डिफ्लेट ब्लॉक की शुरुआत संपीड़ित ब्लॉकों के लिए यह संकेत नहीं देती है कि यह कितना लंबा है । असंगत डेटा को एक असम्पीडित ब्लॉक प्रकार के साथ कोडित किया जा सकता है जिसमें सामने की ओर बाइट्स में 16-बिट आकार होता है, लेकिन संकुचित ब्लॉक नहीं होते हैं: RFC 1951 प्रारूप का वर्णन बहुत आसानी से करता है । डायनेमिक हफ़मैन कोडिंग वाले ब्लॉक में ब्लॉक के सामने का पेड़ होता है (इसलिए डीकंप्रेसर को स्ट्रीम में तलाश नहीं करना पड़ता है), इसलिए कंप्रेसर को लिखने से पहले पूरे (संकुचित) ब्लॉक को मेमोरी में रखना होगा।
अधिकतम बैकवर्ड-रेफरेंस डिस्टेंस केवल 32kiB है, इसलिए कंप्रेसर को मेमोरी में बहुत अधिक असम्पीडित डेटा रखने की आवश्यकता नहीं है, लेकिन यह ब्लॉक आकार को सीमित नहीं करता है। ब्लॉक कई मेगाबाइट लंबे हो सकते हैं। (यह एक चुंबकीय ड्राइव पर भी डिस्क के लायक होने के लिए काफी बड़ा है, बनाम अनुक्रमिक मेमोरी में पढ़ा जाता है और रैम में केवल डेटा लंघन करता है, अगर यह संभव है कि इसके माध्यम से पार्स किए बिना वर्तमान ब्लॉक के अंत का पता लगाना)।
zlib जब तक संभव हो ब्लॉक बनाता है:
मार्क एडलर के अनुसार , zlib केवल एक नया ब्लॉक शुरू करता है जब प्रतीक बफर भर जाता है, जो डिफ़ॉल्ट सेटिंग के साथ 16,383 प्रतीक (शाब्दिक या मैच) है
मैंने seq
(जो कि बेहद बेमानी है और इस तरह शायद एक बड़ा परीक्षण नहीं है) का pv < /tmp/seq1G.gz | gzip -d | tail -c $((1024*1024*1000)) | wc -c
आउटपुट ग़ज़ल में लिया, लेकिन उस पर स्केलेक i7-6700k पर केवल ~ 62 MiB / s का डेटा 3.9GHz पर चलता है, DDR2-2666 RAM के साथ। यह 246MiB / s विघटित डेटा है, जो memcpy
कैश में फिट होने के लिए ब्लॉक आकार के लिए ~ 12 GiB / s की गति की तुलना में मोटा परिवर्तन है ।
(इसके बजाय energy_performance_preference
डिफ़ॉल्ट पर सेट होने के साथ , स्काईलेक के आंतरिक सीपीयू गवर्नर केवल 2.7GHz पर चलने का निर्णय लेते हैं, ~ 43 MiB / संपीड़ित डेटा का उपयोग करते हैं। मैं इसका उपयोग करने के लिए उपयोग करता हूं । संभवतः ऐसी लगातार सिस्टम कॉल वास्तविक सीपीयू-बाउंड की तरह नहीं दिखती हैं। बिजली प्रबंधन इकाई के लिए काम करते हैं।)balance_power
balance_performance
sudo sh -c 'for i in /sys/devices/system/cpu/cpufreq/policy[0-9]*/energy_performance_preference;do echo balance_performance > "$i";done'
TL: DR: zcat | tail -c
CPU एक तेज CPU पर भी बाध्य है, जब तक कि आपके पास बहुत धीमी डिस्क नहीं है। gzip ने उस पर चलने वाले CPU का 100% उपयोग किया (और प्रति घड़ी 1.81 निर्देश चलता था, उसी के अनुसार perf
), और tail
सीपीयू के 0.162 का उपयोग करता था (0.58 IPC)। प्रणाली अन्यथा बेकार थी।
मैं लिनक्स 4.14.11-1-ARCH का उपयोग कर रहा हूं, जिसमें केपीटीआई ने डिफ़ॉल्ट रूप से मेल्टडाउन के आसपास काम करने में सक्षम किया है , इसलिए वे सभी write
सिस्टम कॉल gzip
अधिक महंगे हैं जो वे इस्तेमाल करते थे: /
बिल्ट-इन unzip
या zcat
(लेकिन फिर भी नियमित zlib
डिकोड फ़ंक्शन का उपयोग करके ) चाहने से उन सभी पाइपों को लिखा जा सकेगा, और पूरी घड़ी की गति से चलने के लिए स्काइलेक सीपीयू मिलेंगे। (कुछ प्रकार के लोड के लिए यह डाउनलॉकिंग इंटेल स्काईलेक के लिए अद्वितीय है और बाद में, जिनके पास ओएस से सीपीयू आवृत्ति निर्णय लेना बंद है, क्योंकि उनके पास सीपीयू क्या कर रहा है, इसके बारे में अधिक डेटा है, और तेजी से ऊपर / नीचे रैंप कर सकता है।) सामान्य रूप से अच्छा है, लेकिन यहां स्काईलेक को अधिक रूढ़िवादी गवर्नर सेटिंग के साथ पूर्ण गति तक रैंप नहीं करना पड़ता है)।
कोई सिस्टम कॉल नहीं, बस एक बफर को फिर से लिखना जो L2 कैश में फिट बैठता है जब तक आप अपनी शुरुआती बाइट की स्थिति तक नहीं पहुंचते हैं, तो शायद कम से कम कुछ% अंतर होगा। शायद 10% भी, लेकिन मैं यहां केवल संख्या बना रहा हूं। मैंने यह zlib
देखने के लिए कोई विवरण नहीं दिया है कि कैश कैश फुटप्रिंट कितना बड़ा है, और टीपीबी फ्लश (और इस प्रकार यूओपी-कैश फ्लश) केपीटीआई सक्षम के साथ हर सिस्टम कॉल पर कितना नुकसान होता है।
कुछ सॉफ्टवेयर प्रोजेक्ट हैं जो gzip फाइल फॉर्मेट में एक सीक इंडेक्स जोड़ते हैं । इससे आपको मदद नहीं मिलती है अगर आप किसी को भी आपके लिए मांगने योग्य संपीड़ित फ़ाइलों को बनाने के लिए नहीं पा सकते हैं, लेकिन भविष्य के अन्य पाठकों को लाभ हो सकता है।
मुमकिन है इन परियोजनाओं के न तो एक डिकोड समारोह को पता है कि एक सूचकांक के बिना एक Deflate धारा के माध्यम से छोड़ करने के लिए कैसे, क्योंकि वे केवल काम करने के लिए डिज़ाइन कर रहे हैं जब एक सूचकांक है है उपलब्ध।
- ज़िंगा: सीकेबल और स्प्लिटिबल गज़िप । बड़े ब्लॉक आकार की अनुमति देता है।
- BGZF - अवरुद्ध, बड़ा और बेहतर GZIP! (छोटे अधिकतम ब्लॉक आकार = 64kiB संपीड़न अनुपात को थोड़ा नुकसान पहुंचाता है। एफआईटीटीए जैसे जैव सूचना विज्ञान डेटा के साथ उपयोग के लिए डिज़ाइन किया गया है, जो अक्सर कुछ अजगर पुस्तकालयों में पारदर्शी समर्थन के साथ असम्पीडित उपयोग किया जाता है।)