আমার একটি অনন্য পরিস্থিতি রয়েছে যেখানে আমি এই পৃষ্ঠায় প্রস্তাবিত সমাধানগুলিকে বেনমার্ক করতে পারি, এবং তাই আমি প্রতিটিটির জন্য অন্তর্ভুক্ত রান সময় সহ প্রস্তাবিত সমাধানগুলির একীকরণ হিসাবে এই উত্তরটি লিখছি।
সেট আপ
আমার কাছে প্রতি সারি একটি কী-মান জোড় সহ একটি 3.261 গিগাবাইট ASCII পাঠ্য ডেটা ফাইল রয়েছে। এই ফাইলটিতে মোট ৩,৩৩৯, ৫৫০,৩২০ টি সারি রয়েছে এবং আমার যাওয়া-আসা ভিম সহ আমি চেষ্টা করেছি এমন কোনও সম্পাদকের খোলার বিষয়টি অস্বীকার করে। আমি আবিষ্কার করেছি কেবলমাত্র values 500,000,000 সারি থেকে শুরু হওয়া মানগুলির কিছু অনুসন্ধানের জন্য এই ফাইলটি সাবসেট করা দরকার।
কারণ ফাইলটিতে অনেকগুলি সারি রয়েছে:
- ডেটা সহ দরকারী কিছু করতে আমার সারিগুলির কেবল একটি উপসেট বের করতে হবে।
- আমি যে মূল্যবোধগুলির প্রতি যত্নশীল সেগুলি পর্যন্ত প্রতিটি সারিতে পড়া দীর্ঘ সময় নিতে চলেছে।
- যদি সমাধানটি আমার সারি সারিগুলি পড়ে থাকে এবং বাকী ফাইলটি পড়া চালিয়ে যায় তবে এটি প্রায় 3 বিলিয়ন অপ্রাসঙ্গিক সারিগুলি পড়তে সময় নষ্ট করবে এবং প্রয়োজনীয়তার চেয়ে 6x বেশি সময় নেবে।
আমার সেরা ক্ষেত্রে-পরিস্থিতি এমন একটি সমাধান যা ফাইলের অন্য কোনও সারি না পড়েই কেবল ফাইলটি থেকে কেবল একটি লাইনই বের করে, তবে আমি কীভাবে বাশে এটি সম্পাদন করব তা ভাবতে পারি না।
আমার বিচক্ষণতার উদ্দেশ্যে আমি নিজের সমস্যার জন্য আমার প্রয়োজন 500,000,000 টি সম্পূর্ণ লাইন পড়ার চেষ্টা করব না। পরিবর্তে আমি 3,339,550,320 এর মধ্যে 50,000,000 সারি উত্তোলনের চেষ্টা করব (যার অর্থ পুরো ফাইলটি পড়ার প্রয়োজনে 60x বেশি সময় লাগবে)।
আমি time
প্রতিটি কমান্ড বেঞ্চমার্ক করতে অন্তর্নির্মিতটি ব্যবহার করব ।
বেসলাইন
প্রথমে দেখুন কীভাবে head
tail
সমাধান:
$ time head -50000000 myfile.ascii | tail -1
pgm_icnt = 0
real 1m15.321s
50 মিলিয়ন সারিটির বেসলাইনটি 00: 01: 15.321, যদি আমি 500 মিলিয়ন সারির জন্য সোজা চলে যাই তবে সম্ভবত এটি 12.5 মিনিট হত।
কাটা
আমি এটি সম্পর্কে সন্দেহজনক, তবে এটি শট করার জন্য মূল্যবান:
$ time cut -f50000000 -d$'\n' myfile.ascii
pgm_icnt = 0
real 5m12.156s
এটি চালাতে 00: 05: 12.156 সময় নিয়েছে যা বেসলাইন থেকে অনেক ধীর গতির! আমি নিশ্চিত না যে এটি পুরো ফাইলটি পড়েছে বা থামার আগে মাত্র 50 মিলিয়ন লাইন অবধি রয়েছে, তবে এটি সমস্যার সমাধানযোগ্য সমাধান হিসাবে মনে হচ্ছে না।
awk
আমি কেবল সাথে সমাধানটি চালিয়েছি exit
কারণ আমি পুরো ফাইলটি চালানোর জন্য অপেক্ষা করতে যাচ্ছিলাম না:
$ time awk 'NR == 50000000 {print; exit}' myfile.ascii
pgm_icnt = 0
real 1m16.583s
এই কোডটি 00: 01: 16.583 এ চলেছিল, যা কেবলমাত্র ~ 1 সেকেন্ড ধীর, তবে এখনও বেসলাইনটিতে কোনও উন্নতি হয়নি। এই হারে যদি প্রস্থান কমান্ডটি বাদ দেওয়া হত তবে পুরো ফাইলটি পড়তে সম্ভবত প্রায় ~ 76 মিনিট সময় লাগত!
পার্ল
আমি বিদ্যমান পার্ল সমাধানটিও চালিয়েছি:
$ time perl -wnl -e '$.== 50000000 && print && exit;' myfile.ascii
pgm_icnt = 0
real 1m13.146s
এই কোডটি 00: 01: 13.146 এ চলেছিল, যা বেসলাইন থেকে seconds 2 সেকেন্ড দ্রুত। আমি যদি এটি পুরো 500,000,000 এ চালাই তবে এটি সম্ভবত 12 মিনিট সময় নিতে পারে।
sed
বোর্ডের শীর্ষ উত্তর, এখানে আমার ফলাফল:
$ time sed "50000000q;d" myfile.ascii
pgm_icnt = 0
real 1m12.705s
এই কোডটি 00: 01: 12.705 এ চলেছিল, যা বেসলাইন থেকে 3 সেকেন্ড দ্রুত এবং পার্লের চেয়ে ~ 0.4 সেকেন্ড দ্রুত। আমি যদি এটি পুরো 500,000,000 সারিতে চালাতাম তবে সম্ভবত এটি 12 মিনিট সময় নিতে পারে।
mapfile
আমার কাছে 3.1 বাশ রয়েছে এবং তাই ম্যাপফাইলে সমাধানটি পরীক্ষা করতে পারবেন না।
উপসংহার
দেখে মনে হচ্ছে বেশিরভাগ অংশে head
tail
সমাধানটির উন্নতি করা বেশ কঠিন । সর্বোত্তমভাবে sed
সমাধানটি দক্ষতার মধ্যে 3% ডলার বৃদ্ধি সরবরাহ করে।
(সূত্র দিয়ে গণনা করা শতাংশ % = (runtime/baseline - 1) * 100
)
সারি 50,000,000
- 00: 01: 12.705 (-00: 00: 02.616 = -3.47%)
sed
- 00: 01: 13.146 (-00: 00: 02.175 = -2.89%)
perl
- 00: 01: 15.321 (+00: 00: 00.000 = + 0.00%)
head|tail
- 00: 01: 16.583 (+00: 00: 01.262 = + 1.68%)
awk
- 00: 05: 12.156 (+00: 03: 56.835 = + 314.43%)
cut
সারি 500,000,000
- 00: 12: 07.050 (-00: 00: 26.160)
sed
- 00: 12: 11.460 (-00: 00: 21.750)
perl
- 00: 12: 33.210 (+00: 00: 00.000)
head|tail
- 00: 12: 45.830 (+00: 00: 12.620)
awk
- 00: 52: 01.560 (+00: 40: 31.650)
cut
সারি 3,338,559,320
- 01: 20: 54.599 (-00: 03: 05.327)
sed
- 01: 21: 24.045 (-00: 02: 25.227)
perl
- 01: 23: 49.273 (+00: 00: 00.000)
head|tail
- 01: 25: 13.548 (+00: 02: 35.735)
awk
- 05: 47: 23.026 (+04: 24: 26.246)
cut
awk
এবংsed
এবং আমি নিশ্চিত যে কেউ পার্ল ওয়ান-লাইনার পাশাপাশি আসতে পারে;)