আমি ভেবেছিলাম যে ফাইলটি শুরু থেকে পয়েন্ট পর্যন্ত সংক্ষেপিত করার চেয়ে আরও দক্ষ কিছু করা সম্ভব কিনা? দেখা যাচ্ছে যে উত্তরটি নেই। তবে কিছু সিপিইউতে (স্কাইলেক) zcat | tail
সিপিইউকে পুরো ঘড়ির গতি পর্যন্ত র্যাম্প করে না। নিচে দেখ. একটি কাস্টম ডিকোডার এই সমস্যাটি এড়াতে পারে এবং পাইপ রাইটিং সিস্টেম কলগুলি সংরক্ষণ করতে পারে এবং 10% দ্রুত হতে পারে। (বা পাওয়ার-ম্যানেজমেন্ট সেটিংস মুছে ফেলা না হলে স্কাইলেকে ~ 60% দ্রুত)।
কোনও skipbytes
ফাংশন সহ আপনি কাস্টমাইজড জিলিবের সাথে সর্বোত্তম যেটি করতে পারেন তা হ'ল সংক্ষেপিত ব্লকের পুনর্গঠনের কাজটি না করে শেষের দিকে পৌঁছানোর জন্য একটি সংক্ষেপণ ব্লকের চিহ্নগুলি পার্স করা। একই বাফারটিকে ওভাররাইট করতে এবং ফাইলটিতে এগিয়ে যাওয়ার জন্য zlib এর নিয়মিত ডিকোড ফাংশন কল করার চেয়ে এটি উল্লেখযোগ্যভাবে দ্রুত (সম্ভবত কমপক্ষে 2x) হতে পারে। তবে আমি জানি না কেউ এরকম ফাংশন লিখেছেন কি না। (এবং আমি মনে করি এটি কোনও নির্দিষ্ট ব্লকে ডিকোডার পুনরায় আরম্ভ করার জন্য ফাইলটি বিশেষভাবে লেখা না হলে এটি কাজ করবে না)।
আমি আশা করছিলাম ডিফল্ট ব্লকগুলি ডিকোড না করে এড়িয়ে যাওয়ার কোনও উপায় আছে, কারণ এটি আরও দ্রুত হবে। হাফম্যান ট্রি প্রতিটি ব্লকের শুরুতে প্রেরণ করা হয়, সুতরাং আপনি যে কোনও ব্লকের শুরু থেকে ডিকোড করতে পারেন (আমার মনে হয়)। ওহ, আমি মনে করি হাফম্যান গাছের তুলনায় ডিকোডার রাজ্যটি অনেক বেশি, এটি ডিকোডড ডেটা পূর্ববর্তী 32kiB এবং এটি ডিফল্টরূপে ব্লক সীমানা জুড়ে পুনরায় সেট / ভুলে যায় না। একই বাইটগুলি বারবার উল্লেখ করা যেতে পারে, তাই কেবলমাত্র আক্ষরিকভাবে একবারে দানবীয় সংকুচিত ফাইলে উপস্থিত হতে পারে। (যেমন কোনও লগ ফাইলের মধ্যে, হোস্টনাম সম্ভবত কমপ্রেশন অভিধানে পুরো সময় "গরম" থাকে এবং এর প্রতিটি উদাহরণ পূর্বেরটি উল্লেখ করে, প্রথমটি নয়)।
zlib
ম্যানুয়াল বলেছে তুমি ব্যবহার করতে হবে Z_FULL_FLUSH
যখন কলিং deflate
আপনি সংকুচিত প্রবাহ যে বিন্দু থেকে seekable হতে চাই। এটি "সংক্ষেপণ স্থিতি পুনরায় সেট করে", সুতরাং আমি এটি ব্যতীত ভাবি, পিছনের উল্লেখগুলি পূর্ববর্তী ব্লকে যেতে পারে ( সুতরাং আপনার জিপ ফাইলটি মাঝেমধ্যে পূর্ণ-ফ্লাশ ব্লক (প্রতিটি 1 জি বা কোনও কিছুতে সংকোচনের উপর নগণ্য প্রভাব ফেলবে) দিয়ে লেখা না থাকলে আমি মনে করি যে আপনি যে পয়েন্টটি শুরুতে চান তার চেয়ে বেশি ডিকোডিংয়ের কাজটি আপনাকে করতে হবে চিন্তা। আমার ধারণা আপনি কোনও ব্লকের শুরুতে সম্ভবত শুরু করতে পারবেন না।
এটির বাকীটি তখনই লেখা হয়েছিল যখন আমি ভাবছিলাম যে আপনি যে প্রথম বাইটটি চান তা কেবলমাত্র ব্লকের শুরুটি খুঁজে পাওয়া সম্ভব হবে এবং সেখান থেকে ডিকোড করুন।
তবে দুর্ভাগ্যক্রমে, ডিফল্ট ব্লকের সূচনা সংকুচিত ব্লকগুলির জন্য এটি কত দীর্ঘ তা নির্দেশ করে না । সংকোচনযোগ্য ডেটা একটি সংকোচিত ব্লক প্রকারের সাথে কোড করা যেতে পারে যা সামনের অংশে বাইটে একটি 16-বিট আকার রয়েছে, তবে সংকোচিত ব্লকগুলি না: আরএফসি 1951 ফর্ম্যাটটি সুন্দরভাবে পড়ার জন্য বর্ণনা করে । ডায়নামিক হাফম্যান কোডিং সহ ব্লকগুলির ব্লকের সামনের অংশে গাছ রয়েছে (সুতরাং ডিকম্প্রেসারের প্রবাহে সন্ধান করতে হবে না), তাই লেখার আগে কমপ্রেসরকে পুরো (সংক্ষেপিত) ব্লকটি স্মৃতিতে রাখতে হবে।
সর্বাধিক পিছনের-রেফারেন্স দূরত্বটি কেবলমাত্র 32kiB, সুতরাং সংক্ষেপকটিকে মেমরিতে অনেকটা সঙ্কুচিত ডেটা রাখার দরকার নেই, তবে এটি ব্লকের আকারকে সীমাবদ্ধ করে না। ব্লকগুলি একাধিক মেগাবাইট দীর্ঘ হতে পারে। (এটি ডিস্কের পক্ষে এমনকি চৌম্বকীয় ড্রাইভেও মূল্যবান হওয়া সন্ধানের পক্ষে যথেষ্ট পরিমাণে, বনাম। মেমোরিতে পড়া অনুক্রমিকভাবে এবং কেবলমাত্র র্যামে ডেটা এড়িয়ে যাওয়া, যদি বর্তমানের ব্লকটির পার্সিং না করেই এটি খুঁজে পাওয়া সম্ভব হয়)।
zlib যতক্ষণ সম্ভব ব্লকগুলি তৈরি করে:
মার্ক অ্যাডলারের মতে , প্রতীক বাফারটি পূর্ণ হলে zlib কেবল একটি নতুন ব্লক শুরু করে, যা ডিফল্ট সেটিং সহ 16,383 চিহ্ন (আক্ষরিক বা মিল)
আমি আউটপুট গিজিপ করেছি seq
(যা চূড়ান্ত অনর্থক এবং সম্ভবত এটি একটি দুর্দান্ত পরীক্ষা নয়) তবে pv < /tmp/seq1G.gz | gzip -d | tail -c $((1024*1024*1000)) | wc -c
ডিডিআর ২৪66666 র্যামের সাথে স্কাইলেক আই --6700০০ কে একটি স্কাইলেক আই z-6700০০k এ কেবল ~ 62 মাইবি / এস সংক্ষেপিত ডেটা চালায়। এটি 246MiB / s এর ডেকম্প্রেসড ডেটা, যা memcpy
ক্যাশের সাথে মানানসই আকারের আকারের ব্লক আকারের জন্য ~ 12 GiB / s গতির তুলনায় চম্প পরিবর্তন change
( পরিবর্তে energy_performance_preference
ডিফল্টে সেট করে , স্কাইলকের অভ্যন্তরীণ সিপিইউ গভর্নর কেবল ২.7 গিগাহার্টজ, comp 43 মাইবি / এস সংক্ষেপিত ডেটা চালানোর সিদ্ধান্ত নিয়েছে I আমি এটি টুইট করতে ব্যবহার করি ably সম্ভবত এই জাতীয় ঘন ঘন সিস্টেম কলগুলি আসল সিপিইউ-তেমন লাগে না) পাওয়ার-ম্যানেজমেন্ট ইউনিটে কাজ করুন))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'
টিএল: ডিআর: zcat | tail -c
সিপিইউ একটি দ্রুত সিপিইউতে আবদ্ধ, যদি আপনার খুব ধীর ডিস্ক না থাকে। জিজিপ এটি চালিত সিপিইউর 100% ব্যবহার করে (এবং প্রতি ঘড়ি প্রতি 1.81 নির্দেশাবলীতে দৌড়েছিল perf
), এবং tail
এটি চালিত সিপিইউয়ের 0.162 ব্যবহার করেছে (0.58 আইপিসি)। সিস্টেমটি অন্যথায় বেশিরভাগ অলস ছিল।
আমি লিনাক্স 4.14.11-1-ARCH ব্যবহার করছি, যা মেল্টডাউনের চারপাশে কাজ করতে ডিফল্টরূপে কেপিটিআই সক্ষম করেছে , সুতরাং এই সমস্ত write
সিস্টেমে কল করা gzip
তার আগের চেয়ে বেশি ব্যয়বহুল: /
অন্তর্নির্মিতভাবে অনুসন্ধান করা unzip
বা zcat
(তবে এখনও নিয়মিত zlib
ডিকোড ফাংশনটি ব্যবহার করে ) এই সমস্ত পাইপ লেখার সংরক্ষণ করতে পারে এবং স্কাইলেক সিপিইউগুলি পুরো ঘড়ির গতিতে চালিত করতে পারে। (কিছু ধরণের লোডের জন্য এই ডাউনক্লোকিংটি ইন্টেল স্কাইলকের এবং পরে, যা সিপিইউ ফ্রিকোয়েন্সি সিদ্ধান্ত ওএস থেকে নেওয়া আপলোড করেছে, কারণ সিপিইউ কী করছে সে সম্পর্কে তাদের আরও ডেটা রয়েছে এবং দ্রুত / ডাউন র্যাম্প করতে পারে to সাধারণত ভাল, তবে এখানে স্কাইলেকে আরও রক্ষণশীল গভর্নর সেটিংয়ের সাথে পুরো গতিতে র্যাম্পিং না করার দিকে নিয়ে যায়)।
কোনও সিস্টেম কল নেই, কেবলমাত্র L2 ক্যাশে ফিট করে এমন একটি বাফার পুনর্লিখন করা আপনার পছন্দসই প্রারম্ভিক বাইট পজিশনে পৌঁছানো পর্যন্ত, সম্ভবত কমপক্ষে কয়েক% পার্থক্য আনবে। হতে পারে এমনকি 10%, তবে আমি এখানে কেবল সংখ্যা তৈরি করছি। zlib
কেপিটিআই সক্ষম করার সাথে প্রতিটি সিস্টেম কলটিতে টিএলবি ফ্লাশ (এবং এইভাবে ইউওপ-ক্যাশে ফ্লাশ) কতটা আছে তা দেখার জন্য আমি কোনও বিশদে প্রোফাইল দেইনি।
কয়েকটি সফ্টওয়্যার প্রকল্প রয়েছে যা জিজেপ ফাইল ফর্ম্যাটে সিক ইনডেক্স যুক্ত করে । আপনি যদি কারও জন্য সন্ধানযোগ্য সংক্রামিত ফাইল তৈরি করতে না পারেন তবে এটি আপনাকে সহায়তা করে না, তবে ভবিষ্যতের অন্যান্য পাঠকরা উপকৃত হতে পারেন।
সম্ভবত এই প্রকল্পগুলির কোনওটিরই একটি ডিকোড ফাংশন নেই যা জেনে যায় কীভাবে কোনও সূচক ছাড়াই ডিফল্ট স্ট্রিমটি ছাড়তে হয়, কারণ সেগুলি কেবলমাত্র কোনও সূচক উপলভ্য হলে কাজ করার জন্য তৈরি করা হয় ।