গ্রেপ কীভাবে এত তাড়াতাড়ি চলে?


113

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

বলা হচ্ছে আমি কীভাবে এটি ঘটছে তা অনুধাবন করতে সক্ষম হইনি? ওয়েবে খুব বেশি উপলব্ধ নেই।

যে কেউ এই আমাকে সাহায্য করতে পারেন?


5
এটি ওপেন সোর্স যাতে আপনি নিজের খোঁজ নিতে পারেন। gnu.org/software/grep/devel.html
ড্রাইভ করুন

6
হাস্যকর মাছের আপনার প্রশ্নের ঠিক উত্তর দেওয়ার দুর্দান্ত রচনা আছে: হাস্যকর
ফিশ.com/blog/posts/old-age-and-treachery.html

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

3
আপনার জাভা বাস্তবায়নটি জেভিএম শুরু করতে কত সময় ব্যয় করে এবং আপনার কোডটি কার্যকর করতে এটি কত সময় ব্যয় করে? অথবা এটি আপনার জাভা কোডটিতে আপনি যে অ্যালগরিদম ব্যবহার করেছেন তা হতে পারে; কোনও ও (এন ^ 2) অ্যালগরিদম কোনও ভাষায় ধীর হতে পারে।
কিথ থম্পসন

উত্তর:


169

আপনার প্রশ্নটি GNU grepবিশেষভাবে বিবেচনা করে ধরে নেওয়া । এখানে লেখক মাইক হার্টেলের একটি মন্তব্য:

জিএনইউ গ্রেপটি দ্রুত কারণ এটি প্রতিটি ইনপুট বাইকে দেখে AV

জিএনইউ গ্রেপ দ্রুত কারণ এটি প্রতিদ্বন্দ্বী যে জন্য দেখায় না তার জন্য কয়েকটি কয়েকটি নির্দেশনা কার্যকর করে।

জিএনইউ গ্রেপ সুপরিচিত বায়ার-মুর অ্যালগরিদম ব্যবহার করে, যা লক্ষ্য স্ট্রিংয়ের চূড়ান্ত অক্ষরের জন্য প্রথম দেখায় এবং যখন কোনও মিল না পাওয়া অক্ষর খুঁজে পায় তখন ইনপুটটিতে কতটা এগিয়ে যেতে পারে তা জানাতে একটি অনুসন্ধান সারণী ব্যবহার করে।

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

জিএনইউ গ্রেপ কাঁচা ইউনিক্স ইনপুট সিস্টেম কলগুলি ব্যবহার করে এবং এটি পড়ার পরে ডেটা অনুলিপি করে এড়ানো। তদ্ব্যতীত, জিএনইউ গ্রেপ অ্যাভিডসকে নতুন লাইনে ইনপুট দেয়। নিউলাইনগুলি অনুসন্ধান করা বেশ কয়েকবার একটি ফ্যাক্টর দ্বারা আস্তে আস্তে আস্তে আস্তে আস্তে আস্তে আস্তে আস্তে নামবে কারণ নতুন লাইনের সন্ধানের জন্য এটি প্রতিটি বাইটে দেখতে হবে!

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

এই উত্তরটি এখান থেকে নেওয়া তথ্যের একটি উপসেট ।


41

স্টিভের দুর্দান্ত উত্তর যুক্ত করতে।

এটি ব্যাপকভাবে পরিচিত নাও হতে পারে তবে গ্রাইপ প্রায় সবসময় দ্রুত হয় যখন সংক্ষিপ্তটির চেয়ে লম্বা প্যাটার্ন-স্ট্রিংয়ের জন্য গ্রেপিং করা হয় , কারণ দীর্ঘতর প্যাটার্নে বায়ার-মুর আরও ভাল সাবলাইনারের গতি অর্জনের জন্য লম্বা ধাপে এগিয়ে যেতে পারেন :

উদাহরণ:

# after running these twice to ensure apples-to-apples comparison
# (everything is in the buffer cache) 

$ time grep -c 'tg=f_c' 20140910.log
28
0.168u 0.068s 0:00.26

$ time grep -c ' /cc/merchant.json tg=f_c' 20140910.log
28
0.100u 0.056s 0:00.17

আর লম্বা ফর্মটি 35% দ্রুত!

কিভাবে? বায়ার-মুর প্যাটার্ন-স্ট্রিং থেকে একটি স্কিপ-ফরোয়ার্ড টেবিল তৈরি করে এবং যখনই কোনও অমিল থাকে, স্কিপ টেবিলের ইনপুটটিতে একক চরকে তুলনা করার আগে এটি সম্ভব দীর্ঘতম স্কিপটিকে (শেষ চর থেকে প্রথম দিকে) বেছে নেয়।

বায়ার মুরকে ব্যাখ্যা করার জন্য এখানে একটি ভিডিও রয়েছে (কমড্রহোমারে ক্রেডিট)

আর একটি সাধারণ ভুল ধারণা (জিএনইউ গ্রেপের জন্য) এটি এর fgrepচেয়ে দ্রুত grepfমধ্যে fgrepজন্য 'ফাস্ট' স্ট্যান্ড না, এটি 'সংশোধন' (man পৃষ্ঠা দেখুন) ঘোরা এবং যেহেতু উভয় একই অনুষ্ঠানে, এবং উভয় ব্যবহার হয় বুইয়ার মুর , সেখানে তাদের মধ্যে গতিতে কোনো পার্থক্য যখন fixed- অনুসন্ধানের জন্য এর রেজিএক্সপ্যাক্ট বিশেষ অক্ষর ছাড়াই স্ট্রিং। একমাত্র কারণ আমি ব্যবহারের fgrepযখন কোন RegExp বিশেষ গৃহস্থালির কাজ হয় (যেমন ., []অথবা *) আমি না এটা যেমন হিসেবে ব্যাখ্যা করা যেতে চাই। এবং তারপরেও আরও পোর্টেবল / স্ট্যান্ডার্ড ফর্মটি grep -Fপছন্দ করা হয় fgrep


3
এটি স্বজ্ঞাত যে দীর্ঘ নিদর্শনগুলি আরও দ্রুত। প্যাটার্নটি যদি একটি বাইট হয় তবে গ্রেপকে প্রতিটি বাইট পরীক্ষা করতে হবে। যদি প্যাটার্নটি 4-বাইট হয় তবে এটি 4-বাইট স্কিপগুলি তৈরি করতে পারে। যদি প্যাটার্নটি পাঠ্যের মতো দীর্ঘ হয় তবে গ্রেপ কেবল একটি পদক্ষেপ করতে পারে।
নোল

12
হ্যাঁ, এটি স্বজ্ঞাত - আপনি যদি বুঝতে পারেন যে বায়ার-মুর কীভাবে কাজ করে।
আরিফেল

2
এমনকি অন্যথায় এটি স্বজ্ঞাত। খড়ের
ছাদের

2
"বেশি দিন দ্রুত হওয়া" এর পাল্টা উদাহরণ হ'ল ক্ষেত্রে ব্যর্থ হওয়ার আগে আপনাকে অনেক পরীক্ষা করতে হবে এবং আপনি যেভাবে এগিয়ে যেতে পারবেন না। বলুন যে ফাইলটিতে xs.txt100000000 'x গুলি রয়েছে, এবং আপনি এটি করেন grep yx xs.txt, তবে আসলে এটির চেয়ে কোনও মিল খুঁজে পাওয়া যায় না grep yxxxxxxxxxxxxxxxxxxx xs.txt। বায়ার-মুর-হর্সপুলের বায়ার-মুরের উন্নতি সেই ক্ষেত্রে এগিয়ে যাওয়ার পথে উন্নতি করে, তবে সম্ভবত এটি সাধারণ ক্ষেত্রে কেবল তিনটি মেশিনের নির্দেশনা হতে পারে না।
লর্ড

2
@ টিনো ধন্যবাদ হ্যাঁ, মনে grep/fgrep/egrepহচ্ছে (জিএনইউ) সমস্ত কার্যকর লিঙ্কে কার্যকর হওয়া সমস্ত হার্ডলিঙ্কগুলি চলে গেছে। তারা (এবং অন্যান্য এক্সটেনশনগুলি যেমন z*grep bz*grepউড়ে যা পচে যায়), এখন চারপাশে ছোট ছোট শেল-র্যাপার grep। একক এক্সিকিউটেবল এবং শেল র‌্যাপারগুলির মধ্যে স্যুইচ সম্পর্কিত কিছু আকর্ষণীয় comments তিহাসিক মন্তব্যগুলি
আরিফেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.