একটি গিজিপ-সংকুচিত ফাইলটিতে রেকর্ডের সংখ্যা (লাইন) পাওয়ার দ্রুততম এবং সর্বাধিক কার্যকর উপায়


16

আমি একটি 7.6 গিগাবাইট জিজিপ ফাইলটিতে রেকর্ড গণনা করার চেষ্টা করছি। zcatকমান্ডটি ব্যবহার করে আমি কয়েকটি পন্থা খুঁজে পেয়েছি ।

$ zcat T.csv.gz | wc -l
423668947

এটি কাজ করে তবে এটি অনেক বেশি সময় নেয় (গণনা পেতে 10 মিনিটের বেশি)। আমি আরও কয়েকটি পদ্ধতির চেষ্টা করেছি

$ sed -n '$=' T.csv.gz
28173811
$ perl -lne 'END { print $. }' < T.csv.gz
28173811
$ awk 'END {print NR}' T.csv.gz
28173811

এই তিনটি কমান্ডই খুব দ্রুত কার্যকর করছে তবে 28173811 এর একটি ভুল গণনা দিচ্ছে।

আমি কীভাবে ন্যূনতম সময়ে একটি রেকর্ড গণনা সম্পাদন করতে পারি?


5
আপনার কেন রেকর্ডের সংখ্যা গণনা করা দরকার? যদি আপনি এগুলি প্রক্রিয়া করার আগে এগুলি গণনা করার চেষ্টা করছেন তবে এর অর্থ আপনাকে ফাইলটি দুবার সঙ্কুচিত করতে হবে।
অ্যান্ড্রু হেনেল

3
আপনি কেন এটি করছেন সে সম্পর্কে আরও তথ্য সহায়ক হবে। যদি এটি চলমান কিছু হয় - যা আপনি নিয়মিতভাবে একটি গুচ্ছ ফাইলগুলি সংকোচন করেন এবং পরবর্তী সময়ে রেকর্ডের সংখ্যা জানতে হবে - কেন সেগুলি সংকুচিত হওয়ার কারণে সেগুলি গণনা করবেন না, এবং ফাইলের নাম্বারে নম্বর এম্বেড করবেন না কেন?
জামেস্কফ

3
একটি যান্ত্রিক ডিস্ক থেকে একটি 9.7 গিগাবাইট ফাইল পড়া সহজাতভাবে ধীর হয়। ফাইলটি একটি এসএসডি-তে সঞ্চয় করুন, এবং দেখুন গানজিপ / জেডক্যাট কত দ্রুত চলে। তবে @ জামেস্কেফ যেমন বলেছে, ফাইলের নাম, বা টিজিজেডের একটি ফাইলে লাইনকাউন্ট সংরক্ষণ করুন এবং সেই ফাইলটি বের করা আরও দ্রুত হবে।
চককট্রিল

2
আপনি এই কাজটি এড়াতে পারবেন না এমন ভাল তাত্ত্বিক কারণ রয়েছে। একটি সংকোচনের বিন্যাস যা আপনাকে "এটি সংক্ষেপিত না করে" ডেটার কিছু দরকারী সম্পত্তি নির্ধারণ করতে দেয় সংজ্ঞা অনুসারে এটি খুব ভাল কোনও সংক্ষেপণ বিন্যাস হিসাবে ভাল হতে পারে না :)
হাবসগুলি

উত্তর:


28

sed, perlএবং awkকমান্ড আপনি সঠিক হতে পারে উল্লেখ, কিন্তু তারা সব পড়ি যে সংকুচিত যে ডেটা এবং গন্য সম্পর্কে newline অক্ষর। এই নিউলাইন অক্ষরগুলিকে সঙ্কুচিত ডেটাতে নিউলাইন অক্ষরগুলির সাথে কোনও সম্পর্ক নেই।

সঙ্কুচিত তথ্যের রেখার সংখ্যা গণনা করার জন্য, এটি সঙ্কুচিত করার কোনও উপায় নেই। আপনার সাথে zcatযোগাযোগ করা সঠিক পন্থা এবং যেহেতু ডেটা এত বড়, তাই হবে এটা কমপ্রেস মুক্ত করতে সময় লাগে।

সংক্ষিপ্তকরণ gzipএবং ডিকম্প্রেশন নিয়ে কাজ করে এমন বেশিরভাগ ইউটিলিটিগুলি সম্ভবত এটির জন্য একই ভাগ করা লাইব্রেরি রুটিন ব্যবহার করবে। এটা গতি বাড়াতে আপ করার একমাত্র উপায় একটি বাস্তবায়ন এটি হবে zlibরুটিন যে একরকম দ্রুত ডিফল্ট বেশী, এবং যেমন পুনর্নির্মাণের zcatসেই ব্যবহার করতে।


11
এটি একটি তুচ্ছ প্রোগ্রামিং অনুশীলন হবে, তবে সম্ভব do পুরো বিষয়টি পুনর্নির্মাণ না করা হয়zcat । এর কাজের একটি উল্লেখযোগ্য অংশ zcatহ'ল আসল আউটপুট উত্পন্ন করা। তবে আপনি যদি কেবল \nঅক্ষর গণনা করেন তবে এটি প্রয়োজনীয় নয়। gzipসংক্ষিপ্তকরণ মূলত ছোট স্ট্রিং দ্বারা সাধারণ দীর্ঘ স্ট্রিংগুলি প্রতিস্থাপন করে কাজ করে। সুতরাং আপনাকে কেবল অভিধানে থাকা দীর্ঘ স্ট্রিংগুলির যত্ন নিতে হবে \nএবং এর (ভারী) উপস্থিতি গণনা করতে হবে। যেমন ইংরেজি নিয়মের কারণে, .\nএটি একটি সাধারণ 16 বিট স্ট্রিং।
এমসাল্টাররা 14

19

আনপিগ ব্যবহার করুন।

কুসালানন্দের উত্তরটি সঠিক, আপনার সম্পূর্ণ বিষয়বস্তু স্ক্যান করার জন্য আপনাকে পুরো ফাইলটি সঙ্কুচিত করতে হবে/bin/gunzipএটি একক কোরতে যত দ্রুত সম্ভব এটি করে canপিগজ একটি সমান্তরাল বাস্তবায়ন gzipযা একাধিক কোর ব্যবহার করতে পারে।

দুঃখের বিষয়, সাধারণ জিজিপ ফাইলগুলির ডেকম্প্রেশন নিজেই সমান্তরাল করা যায় না, তবে এর pigzএকটি উন্নত সংস্করণ সরবরাহ করা হয় gunzip,unpigz যে যেমন, পড়ার লেখা, এবং একটি পৃথক থ্রেড checksumming যেমন সংশ্লিষ্ট কাজ করে। কিছু দ্রুত মানদণ্ডে, আমার কোর আই 5 মেশিনের unpigzচেয়ে প্রায় দ্বিগুণ দ্রুত gunzip

pigzআপনার পছন্দসই প্যাকেজ পরিচালকের সাথে ইনস্টল করুন এবং এর unpigzপরিবর্তে gunzipবা unpigz -cপরিবর্তে ব্যবহার করুনzcat । সুতরাং আপনার আদেশটি হয়ে যায়:

$ unpigz -c T.csv.gz | wc -l

এই সমস্ত ধারণা করে যে বাধাটি অবশ্যই সিপিইউ, ডিস্ক নয়, অবশ্যই।


4
আমার pigzম্যান পৃষ্ঠাতে বলা হয়েছে যে ডিকম্প্রেশনকে সমান্তরাল করা যায় না, কমপক্ষে সেই উদ্দেশ্যে বিশেষভাবে প্রস্তুত ডিফল্ট স্ট্রিম ছাড়া না। ফলস্বরূপ, পিগজ ডিকম্প্রেশনের জন্য একটি একক থ্রেড (মূল থ্রেড) ব্যবহার করে তবে পড়া, লেখার জন্য এবং গণনা পরীক্ষা করার জন্য আরও তিনটি থ্রেড তৈরি করবে, যা কিছু পরিস্থিতিতে ডিকম্প্রেশনকে গতিময় করতে পারে । তবুও, আপনার মতো আমি এটি খুঁজে পাই কমপক্ষে দ্বিগুণ দ্রুততর gzip, যদি না প্যারালালিজমের কারণে
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস ভাল পয়েন্ট! এটি ডিকম্প্রেশনটির জন্য হালকা হতাশার গতির ব্যাখ্যা দেয়। এই তথ্য আরও ভাল প্রতিফলিত করার জন্য আমি আমার পোস্ট সম্পাদনা করেছি।
মার্সেলম

5

সমস্ত পাইপলাইনগুলির সাথে সমস্যা হ'ল আপনি মূলত কাজ দ্বিগুণ করছেন। ডিকম্প্রেশনটি কত তাড়াতাড়ি হোক না কেন, ডেটাটিকে অন্য প্রক্রিয়াতে বন্ধ করে দেওয়া দরকার।

পার্লের পার্লিও :: জিজিপ রয়েছে যা আপনাকে সরাসরি জিপিড স্ট্রিম পড়তে দেয়। অতএব, এটির সুবিধার প্রস্তাব দেওয়া যেতে পারে যদিও এর পচনশীলতার গতি এর সাথে মেলে না unpigz:

#!/usr/bin/env perl

use strict;
use warnings;

use autouse Carp => 'croak';
use PerlIO::gzip;

@ARGV or croak "Need filename\n";

open my $in, '<:gzip', $ARGV[0]
    or croak "Failed to open '$ARGV[0]': $!";

1 while <$in>;

print "$.\n";

close $in or croak "Failed to close '$ARGV[0]': $!";

আমি এটি ১৩ এমবি গিজিপ সংক্ষিপ্ত ফাইল (১.৪ গিগাবাইটে কমিয়ে আনা) এর সাথে চেষ্টা করেছি 16 জিবি র‌্যাম সহ একটি পুরানো 2010 ম্যাকবুক প্রো এবং 8 জিবি র‌্যাম সহ একটি পুরানো থিঙ্কপ্যাড টি 400 ইতিমধ্যে ক্যাশে থাকা ফাইলটির সহ । ম্যাক-তে, পার্ল স্ক্রিপ্টটি পাইপলাইনগুলি (5 সেকেন্ড বনাম 22 সেকেন্ড) ব্যবহারের চেয়ে উল্লেখযোগ্যভাবে দ্রুত ছিল, তবে আর্চলিনাক্সে এটি আনপিগের কাছে হেরেছে:

$ সময় -পি। / জিজিএলসি.পিএল স্পেস.gz 
1154737
আসল 4.49
ব্যবহারকারী 4.47
sys 0.01

বনাম

$ সময় -p আনপিগ-সি স্পেস.gz | wc -l
1154737
আসল 3.68
ব্যবহারকারী 4.10
sys 1.46

এবং

$ সময় -p zcat spy.gz | wc -l
1154737
বাস্তব 6.41
ব্যবহারকারী 6.08
sys 0.86

স্পষ্টতই, unpigz -c file.gz | wc -lগতির ক্ষেত্রে উভয়ই এখানে বিজয়ী। এবং, যে সহজ কমান্ড লাইন অবশ্যই একটি প্রোগ্রাম লিখতে বীট, যদিও সংক্ষিপ্ত।


1
আমি মনে করি আপনি ডিকম্প্রেশন গণনার তুলনায় দুটি প্রক্রিয়ার মধ্যে ডেটা সরিয়ে নিতে প্রয়োজনীয় সংস্থাগুলিকে ব্যাপকভাবে মূল্যায়ন করছেন। বিভিন্ন পদ্ধতির বেঞ্চমার্কিং চেষ্টা করুন;)
মার্সেলম

2
@ সিনান্নার আমার x86_64 লিনাক্স সিস্টেমে (এছাড়াও পুরানো হার্ডওয়্যার) gzip | wcআপনার পার্ল স্ক্রিপ্টের তুলনায় একই গতি রয়েছে। এবং pigz | wcদ্বিগুণ দ্রুত। gzipএকই গতিতে রান নির্বিশেষে যদি আমি আউটপুট লিখতে, / dev / মধ্যে ফাঁকা বা নল wcআমি কি বিশ্বাস করি যে "gzip, গ্রন্থাগার" Perl দ্বারা ব্যবহৃত দ্রুত gzip, কমান্ড লাইন টুল চেয়ে হয়। পাইপগুলির সাথে আবার অন্য কোনও ম্যাক / ডারউইনের নির্দিষ্ট সমস্যা রয়েছে। এটি এখনও আশ্চর্যজনক যে এই পার্ল সংস্করণটি মোটেই প্রতিযোগিতামূলক।
rudimeier

1
আমার x86_64 লিনাক্স ইনস্টল-এ, এটি এর চেয়ে zcatআরও ভাল এবং খারাপটি বলে মনে হচ্ছে unpigz। ম্যাকের তুলনায় লিনাক্স সিস্টেমে পাইপলাইনটি কত গতিযুক্ত তা দেখে আমি অবাক হয়েছি। আমি প্রত্যাশা করছিলাম না, যদিও আমার একবার হওয়া উচিত ছিল যদিও আমি একই প্রোগ্রামটি খালি ধাতুর চেয়ে সিপিইউ লিমিটেড লিনাক্স ভিএম-তে একই ম্যাকের উপর দ্রুত ছুটে এসেছি।
সিনান Ünür

1
ইহা আকর্ষণীয়; আমার সিস্টেমে (দেবিয়ান 8.8 এএমডি 64, কোয়াড কোর আই 5), পার্ল স্ক্রিপ্টটি কিছুটা ধীরে ধীরে ... 109M .gz ফাইলটি 1.1G পাঠের সংক্ষেপিত, zcat | wc -lআপনার পার্ল স্ক্রিপ্টের জন্য নিয়মিত 5.4 সেকেন্ড এবং 5.5 সেকেন্ড সময় নেয় । সত্যি বলতে, আমি এখানে যে ভিন্নতাগুলি লোকেরা রিপোর্ট করছে তাতে আমি আশ্চর্য হয়েছি, বিশেষত লিনাক্স এবং ম্যাকস এক্স এর মধ্যে!
মার্সেলেম

আমি জানি না যে আমি আমার ম্যাকে যা দেখছি তা সাধারণ করতে পারি, কিছু অদ্ভুত কিছু চলছে। সংক্ষেপিত ১.৪ গিগাবাইট ফাইল সহ, wc -l2.5 সেকেন্ড সময় নেয়। gzcat compressed.gz > /dev/null২.7 সেকেন্ড সময় নেয়। তবুও, পাইপলাইনে 22 সেকেন্ড সময় লাগে। আমি যদি জিএনইউ চেষ্টা করি wcতবে ডিকম্প্রেসড ফাইলটিতে এটি কেবল অর্ধেক সেকেন্ড সময় নেয়, তবে পাইপলাইনে 22 সেকেন্ড সময় নেয়। GNU zcatকার্যকর করতে দ্বিগুণ সময় নেয় zcat compressed.gz > /dev/null। এটি ম্যাভেরিক্স, পুরানো কোর 2 ডুয়ো সিপিইউ, 16 জিবি র‌্যাম, ক্রুশিয়াল এমএক্স 100 এসএসডি।
সিনান Ünür

4

কুসালানন্দের উত্তর বেশিরভাগই সঠিক। লাইনগুলি গণনা করতে আপনাকে নতুন লাইনের সন্ধান করতে হবে। তবে তাত্ত্বিকভাবে ফাইলটিকে সম্পূর্ণ সঙ্কুচিত না করেই নিউলাইনগুলি অনুসন্ধান করা সম্ভব।

gzip ডিফল্ট সংক্ষেপণ ব্যবহার করে। ডিফল্ট হ'ল এলজেড 7777 এবং হাফম্যান এনকোডিংয়ের সংমিশ্রণ। নিউলাইনের জন্য কেবল হাফম্যান সিম্বল নোড বের করার এবং বাকী অংশটিকে উপেক্ষা করার উপায় রয়েছে। L277 ব্যবহার করে এনকোড করা নতুন লাইনের সন্ধানের প্রায় একটি উপায় রয়েছে, বাইট গণনা রাখুন এবং সমস্ত কিছু উপেক্ষা করুন।

সুতরাং আইএমএইচও তার তাত্ত্বিকভাবে সম্ভব আনপিগ বা জেডগ্রিপের চেয়ে আরও কার্যকর সমাধান নিয়ে আসতে পারে। এটি অবশ্যই ব্যবহারিক নয় বলে বলা হচ্ছে (যদি না কেউ ইতিমধ্যে এটি সম্পন্ন না করে)।


7
এই ধারণার একটি প্রধান সমস্যা হ'ল ডিফল্ট দ্বারা ব্যবহৃত হাফম্যান প্রতীকগুলি এলজেড 7777 সংক্ষেপের পরে বিট সিকোয়েন্সগুলির সাথে সামঞ্জস্যপূর্ণ , সুতরাং সঙ্কুচিত ফাইলটিতে তাদের এবং ইউ + 000A অক্ষরের মধ্যে কোনও সহজ সম্পর্ক থাকতে পারে। উদাহরণস্বরূপ, সম্ভবত একটি হাফম্যান প্রতীক মানে "শেষ পাঁচ বিট" means তারপরে "\ n" এর প্রথম তিনটি বিট এবং অন্য প্রতীকটির অর্থ "" n "এর শেষ পাঁচটি বিট" টি "এর আটটি বিট অনুসরণ করে।
zwol

@zwol No, ডিফল্ট অ্যালগরিদমের LZ77 অংশটি বাইট সিকোয়েন্সগুলি সংকুচিত করে, বিট সিকোয়েন্সগুলি নয়। en.wikedia.org/wiki/DEFLATE# ডুপ্লিকেট_ স্ট্রিং_ইলিমিনেশন
রস রিজ

1
@ রোসরিজ হু, আমি এটি জানতাম না, তবে আমি মনে করি না যে এটি আমার যা বলেছিল তা অকার্যকর করে দেয়। যাও Huffman প্রতীক পারেন, এটা যে রেফারেন্স পরবর্তী অনুচ্ছেদে উপর ভিত্তি করে আমার কাছে মনে হচ্ছে, প্রতিটি বিট একটি পরিবর্তনশীল সংখ্যা প্রসারিত করবে, তারা বাইটের একটি পূর্ণ সংখ্যা উত্পাদন করতে হবে না।
zwol

1
@ জওয়ল শিওর, আপনাকে বিট স্ট্রিমে হাফম্যান কোড বিট সিকোয়েন্সগুলির সাথে মিল খুঁজে বের করতে হবে তবে এই উত্তরটি অন্যথায় প্রস্তাব দেয় না। এই উত্তরের সমস্যাটি হ'ল হফম্যান কোডগুলি শেষ পর্যন্ত কোনটি নতুন লাইন অক্ষর উত্পন্ন করে তা নির্ধারণ করা সহজ নয়। LZ77 কোডগুলি যা নতুন লাইনের উত্পন্ন করে স্লাইডিং উইন্ডোটি চলার সাথে সাথে ক্রমাগত পরিবর্তন হয়, যার অর্থ হাফম্যান কোডগুলিও পরিবর্তিত হচ্ছে। আপনাকে আউটপুট অংশ ব্যতীত পুরো ডিকম্প্রেশন অ্যালগরিদম এবং স্লাইডিং উইন্ডোর কিছু অংশ বাস্তবায়ন করতে হবে যেহেতু আপনি কেবলমাত্র নতুন লাইনে আগ্রহী।
রস রিজ

1

ব্যবহার করা যেতে পারে zgrepসঙ্গে -cপতাকা, এবং $প্যারামিটার।

এই ক্ষেত্রে -c কমান্ডটি মিলিয়ে গেছে লাইনগুলির আউটপুট সংখ্যার নির্দেশ দিন এবং রেজেক্স line লাইনের শেষের সাথে মেলে যাতে এটি প্রতিটি লাইন বা ফাইলের সাথে মেলে।

zgrep -c $ T.csv.gz 

@ StéphaneChazelas দ্বারা মন্তব্য হিসাবে - zgrepশুধুমাত্র একটি স্ক্রিপ্ট প্রায় zcatএবং grepএবং এটি মূল প্রস্তাবনায় অনুরূপ কর্মক্ষমতা প্রদান করা উচিতzcat | wc -l


2
হাই ইয়ারন উত্তরের জন্য ধন্যবাদ zgrep এমনকি zcat যতটা সময় নিচ্ছে আমার মনে হয় এমন আরও কিছু পদ্ধতির সন্ধান করতে পারে
রাহুল

8
zgrepসাধারণত একটি স্ক্রিপ্ট যা ডেটা সঙ্কুচিত করতে এবং এটিতে ফিড দেওয়ার জন্য zcatঅনুরূপ (অনুরূপ gzip -dcq) অনুরোধ করে grep, তাই সাহায্য করবে না।
স্টাফেন চেজেলাস

1
@ স্টাফেনচাজেলাস - মন্তব্যের জন্য ধন্যবাদ, আমার উত্তরটি প্রতিফলিত করতে আপডেট করুন।
ইয়ারন

0

আপনি দেখতে পাচ্ছেন, বেশিরভাগ উত্তর কী তা পারে তা অনুকূল করতে চেষ্টা করে: প্রসঙ্গের স্যুইচগুলির সংখ্যা এবং আন্তঃ প্রক্রিয়া আইও। কারণটি হ'ল, এখানেই আপনি সহজেই অনুকূলিত করতে পারেন।

এখন সমস্যাটি হ'ল এর সংস্থানটির সংস্থান সংস্থার প্রয়োজনের তুলনায় এটির সংস্থান প্রয়োজন প্রায় নগণ্য। এই কারণেই অপ্টিমাইজেশানগুলি সত্যিকার অর্থে কোনও দ্রুত তৈরি করে না।

যেখানে এটি সত্যই ত্বরান্বিত হতে পারে, এটি হবে একটি সংশোধিত আন-জিজিপ (অর্থাত্ সংক্ষেপণ) অ্যালগরিদম, যা ডিকম্প্রেসড ডেটা স্ট্রিমের প্রকৃত উত্পাদনকে ছাড়বে; বরং এটি শুধুমাত্র নতুন লাইন সংখ্যা গণনা করে -কম্প্রেস প্রবাহ থেকে সংকুচিত করুন। এটি শক্ত হবে, এর জন্য জিজিপের আলগোরিদিম ( এলজেডাব্লু এবং হাফম্যান সংকোচনের অ্যালগরিদমের কিছু সংমিশ্রণ ) সম্পর্কে গভীর জ্ঞানের প্রয়োজন হবে । এটি যথেষ্ট সম্ভাবনাময়, যে অ্যালগরিদম বিদ্যুতের সাথে ডিকম্প্রেশন সময়টিকে উল্লেখযোগ্যভাবে অনুকূল করা সম্ভব করে না, আমাদের কেবল নিউলাইন গণনাগুলি জানতে হবে। এটি সম্ভব হলেও, মূলত একটি নতুন জিজিপ ডিকম্প্রেশন লাইব্রেরি তৈরি করা উচিত ছিল (এটি জানা না থাকলে এটি বিদ্যমান নেই)।

আপনার প্রশ্নের বাস্তবসম্মত উত্তরটি হ'ল না, আপনি এটিকে উল্লেখযোগ্যভাবে দ্রুততর করতে পারবেন না।

হতে পারে আপনি কিছু সমান্তরাল জিজিপ ডিকম্প্রেশন ব্যবহার করতে পারেন, যদি এটি বিদ্যমান থাকে। এটি সংক্ষেপনের জন্য একাধিক সিপিইউ কোর ব্যবহার করতে পারে। যদি এটির অস্তিত্ব না থাকে তবে এটি তুলনামূলকভাবে সহজেই বিকাশিত হতে পারে।

জন্য ভাবে XZ লস , একটি সমান্তরাল সংকোচকারী (pxz) বিদ্যমান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.