কিভাবে RegexOptions.Compiled কাজ করে?


169

আপনি যখন কোনও নিয়মিত প্রকাশকে সংকলিত হতে চিহ্নিত করেন তখন দৃশ্যের পিছনে কী চলছে? এটি কীভাবে নিয়মিত প্রকাশের তুলনায় আলাদা / তুলনা করে?

এই তথ্য ব্যবহার করে, কর্মক্ষমতা বৃদ্ধির তুলনায় যখন গণনার ব্যয় নগণ্য তখন আপনি কীভাবে নির্ধারণ করবেন?


উত্তর:


302

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

আপনি যদি এই পতাকাটি নির্দিষ্ট না করেন তবে আপনার নিয়মিত অভিব্যক্তিটিকে "ব্যাখ্যা করা" হিসাবে বিবেচনা করা হবে।

এই উদাহরণটি ধরুন:

public static void TimeAction(string description, int times, Action func)
{
    // warmup
    func();

    var watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < times; i++)
    {
        func();
    }
    watch.Stop();
    Console.Write(description);
    Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}

static void Main(string[] args)
{
    var simple = "^\\d+$";
    var medium = @"^((to|from)\W)?(?<url>http://[\w\.:]+)/questions/(?<questionId>\d+)(/(\w|-)*)?(/(?<answerId>\d+))?";
    var complex = @"^(([^<>()[\]\\.,;:\s@""]+"
      + @"(\.[^<>()[\]\\.,;:\s@""]+)*)|("".+""))@"
      + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
      + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
      + @"[a-zA-Z]{2,}))$";


    string[] numbers = new string[] {"1","two", "8378373", "38737", "3873783z"};
    string[] emails = new string[] { "sam@sam.com", "sss@s", "sjg@ddd.com.au.au", "onelongemail@oneverylongemail.com" };

    foreach (var item in new[] {
        new {Pattern = simple, Matches = numbers, Name = "Simple number match"},
        new {Pattern = medium, Matches = emails, Name = "Simple email match"},
        new {Pattern = complex, Matches = emails, Name = "Complex email match"}
    })
    {
        int i = 0;
        Regex regex;

        TimeAction(item.Name + " interpreted uncached single match (x1000)", 1000, () =>
        {
            regex = new Regex(item.Pattern);
            regex.Match(item.Matches[i++ % item.Matches.Length]);
        });

        i = 0;
        TimeAction(item.Name + " compiled uncached single match (x1000)", 1000, () =>
        {
            regex = new Regex(item.Pattern, RegexOptions.Compiled);
            regex.Match(item.Matches[i++ % item.Matches.Length]);
        });

        regex = new Regex(item.Pattern);
        i = 0;
        TimeAction(item.Name + " prepared interpreted match (x1000000)", 1000000, () =>
        {
            regex.Match(item.Matches[i++ % item.Matches.Length]);
        });

        regex = new Regex(item.Pattern, RegexOptions.Compiled);
        i = 0;
        TimeAction(item.Name + " prepared compiled match (x1000000)", 1000000, () =>
        {
            regex.Match(item.Matches[i++ % item.Matches.Length]);
        });

    }
}

এটি 3 টি নিয়মিত এক্সপ্রেশন 4 টি পরীক্ষা করে। প্রথমে এটি একবারে ম্যাচের বাইরে একক পরীক্ষা করে (সংকলিত বনাম সংকলিত)। দ্বিতীয় এটি পুনরাবৃত্তি ম্যাচগুলি পরীক্ষা করে যা একই নিয়মিত অভিব্যক্তি পুনরায় ব্যবহার করে।

আমার মেশিনে ফলাফল (প্রকাশের মধ্যে সংকলিত, কোনও ডিবাগার সংযুক্ত নেই)

1000 একক ম্যাচ (রেগেক্স, মিল এবং নিষ্পত্তি)

প্রকার | প্ল্যাটফর্ম | তুচ্ছ সংখ্যা | সাধারণ ইমেল চেক | অতিরিক্ত ইমেল চেক
-------------------------------------------------- ----------------------------
ব্যাখ্যা করা | x86 | 4 এমএস | 26 এমএস | 31 এমএস
ব্যাখ্যা করা | x64 | 5 এমএস | 29 এমএস | 35 এমএস
সংকলিত | x86 | 913 এমএস | 3775 এমএস | 4487 এমএস
সংকলিত | x64 | 3300 এমএস | 21985 এমএস | 22793 এমএস

১,০০,০০০ ম্যাচ - রেজেক্স অবজেক্টটি পুনরায় ব্যবহার করা হচ্ছে

প্রকার | প্ল্যাটফর্ম | তুচ্ছ সংখ্যা | সাধারণ ইমেল চেক | অতিরিক্ত ইমেল চেক
-------------------------------------------------- ----------------------------
ব্যাখ্যা করা | x86 | 422 এমএস | 461 এমএস | 2122 এমএস
ব্যাখ্যা করা | x64 | 436 এমএস | 463 এমএস | 2167 এমএস
সংকলিত | x86 | 279 এমএস | 166 এমএস | 1268 এমএস
সংকলিত | x64 | 281 এমএস | 176 এমএস | 1180 এমএস

এই ফলাফলগুলি দেখায় যে সংকলিত নিয়মিত ভাবগুলি cases০% পর্যন্ত দ্রুততর হতে পারে আপনি যেখানে Regexবস্তুটি পুনরায় ব্যবহার করবেন । তবে কিছু ক্ষেত্রে নির্মাণের জন্য ধীর গতিতে 3 টিরও বেশি অর্ডার হতে পারে।

এটি আরও দেখায় যে নিয়মিত এক্সপ্রেশন সংকলনের ক্ষেত্রে .NET এর x64 সংস্করণটি 5 থেকে 6 গুণ ধীর হতে পারে ।


প্রস্তাবটি হ'ল উভয় ক্ষেত্রেই সংকলিত সংস্করণ ব্যবহার করা উচিত

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

কাজগুলিতে স্প্যানার, রেজেক্স ক্যাশে

নিয়মিত এক্সপ্রেশন ইঞ্জিনটিতে একটি এলআরইউ ক্যাশে থাকে যা সর্বশেষ 15 নিয়মিত অভিব্যক্তি ধারণ করে যা Regexক্লাসে স্থির পদ্ধতি ব্যবহার করে পরীক্ষা করা হয়েছিল ।

উদাহরণস্বরূপ: Regex.Replace, Regex.Matchইত্যাদি .. সব ব্যবহার Regex ক্যাশে।

সেট করে ক্যাশের আকার বাড়ানো যেতে পারে Regex.CacheSize। এটি আপনার অ্যাপ্লিকেশনটির জীবন চক্রের সময় যে কোনও সময় আকারে পরিবর্তনগুলি গ্রহণ করে।

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

এই ক্যাশেটি একটি তুচ্ছ এলআরইউ ক্যাশে, এটি একটি সাধারণ ডাবল লিঙ্কযুক্ত তালিকা ব্যবহার করে প্রয়োগ করা হয়। যদি আপনি এটি 5000 এ বাড়িয়েছেন এবং স্থির সহায়কদের 5000 টি আলাদা কল ব্যবহার করেন, তবে প্রতিটি নিয়মিত প্রকাশের নির্মাণ 5000 আগে এটিকে ক্যাশে রেখেছিল তা নির্ধারণের জন্য ক্রল করবে। চেকটির চারপাশে একটি লক রয়েছে, যাতে চেকটি সমান্তরালতা হ্রাস করতে পারে এবং থ্রেড ব্লকিংয়ের সূচনা করতে পারে।

এই জাতীয় মামলা থেকে নিজেকে রক্ষা করার জন্য সংখ্যাটি বেশ কম সেট করা হয়েছে, যদিও কিছু ক্ষেত্রে এটি বাড়ানো ছাড়া আপনার কোনও বিকল্প নাও থাকতে পারে।

আমার দৃ strong় সুপারিশটি কোনও স্থিতিশীল সহায়কের কাছে বিকল্পটি কখনই পাস করা হবে নাRegexOptions.Compiled

উদাহরণ স্বরূপ:

\\ WARNING: bad code
Regex.IsMatch("10000", @"\\d+", RegexOptions.Compiled)

কারণ যে আপনি LRU ক্যাশে একটি ভারী ভারী মিস মিস ঝুঁকিপূর্ণ যা একটি দুর্দান্ত ব্যয় সংকলন ট্রিগার করবে । তদতিরিক্ত, আপনি যে লাইব্রেরিগুলির উপর নির্ভরশীল সেগুলি কী করছে সে সম্পর্কে আপনার কোনও ধারণা নেই, তাই ক্যাশে সম্ভাব্যতম আকারের নিয়ন্ত্রণ বা ভবিষ্যদ্বাণী করার সামর্থ্য নেই ।

আরও দেখুন: ছাত্রলীগের টিম ব্লগ


দ্রষ্টব্য : এটি .NET 2.0 এবং .NET 4.0 এর জন্য প্রাসঙ্গিক। ৪.৪-তে কিছু প্রত্যাশিত পরিবর্তন রয়েছে যার ফলে এটি সংশোধিত হতে পারে।


11
দুর্দান্ত উত্তর। আমার নিজের উদ্দেশ্যে আমি প্রায়শই Compiledওয়েবসাইট কোড ব্যবহার করি যেখানে আমি আসলে একটি স্ট্যাটিক (অ্যাপ্লিকেশন-বিস্তৃত) Regexবস্তুটি সঞ্চয় করি। সুতরাং Regexআইআইএস অ্যাপ্লিকেশন শুরু করার পরে কেবলমাত্র একবারই তৈরি করতে হবে এবং তারপরে হাজারবার পুনরায় ব্যবহার করা হবে। যতক্ষণ অ্যাপ্লিকেশন ঘন ঘন পুনরায় আরম্ভ হয় না ততক্ষণ এটি কাজ করে।
স্টিভ ওয়ারথাম

W00! এই তথ্যটি আমার প্রসেসটি 8-13 ঘন্টা থেকে 30 মিনিট পর্যন্ত বাড়িয়ে তুলতে সহায়তা করে। ধন্যবাদ!
রবার্ট খ্রিস্ট

3
দুর্দান্ত উত্তর স্যাম, সংস্করণ> 4.5 এ কী পরিবর্তন হয়েছে সে সম্পর্কে আপনি আপডেট করতে পারবেন? (আমি জানি আপনি কিছুক্ষণ আগে নিজের স্ট্যাকটি পরিবর্তন করেছেন ...)
জিডোরন মনিকা 24

@gdoronissupportingMonica নেট 5.0 তে কিছু রেগেক্সের পারফরম্যান্স উন্নতি হয়েছে। আমি এই জন্য একটি ব্লগ পোস্ট দেখেছি। আপনি এখানে
ক্যাপোজেড

42

ছাত্রলীগ টিম ব্লগের এই এন্ট্রিটি একটি সুন্দর ওভারভিউ দেয়: " নিয়মিত এক্সপ্রেশন পারফরম্যান্স "।

সংক্ষেপে, তিন ধরণের রেইগেক্স রয়েছে (প্রতিটি পূর্বের তুলনায় দ্রুত কার্যকর হচ্ছে):

  1. ব্যাখ্যা করা

    ফ্লাইতে তৈরি করা দ্রুত, কার্যকর করতে ধীর

  2. সংকলিত (যাকে আপনি জিজ্ঞাসা করছেন বলে মনে হয়)

    ফ্লাইতে তৈরি করা ধীর, কার্যকর করতে দ্রুত (লুপগুলিতে কার্যকর করার জন্য ভাল)

  3. প্রাক কম্পাইল

    কার্যকর করার জন্য দ্রুত, আপনার অ্যাপ্লিকেশনটির সংকলন সময়ে (কোনও রান-টাইম তৈরির জরিমানা নেই) তৈরি করুন

সুতরাং, যদি আপনি কেবল একবারই রেজেক্স সম্পাদন করতে চান, বা আপনার অ্যাপ্লিকেশনটির একটি অ-কার্য-সম্পাদন-সমালোচনামূলক বিভাগে (যেমন ব্যবহারকারী ইনপুট বৈধকরণ), আপনি বিকল্প 1 এর সাথে ভাল আছেন।

যদি আপনি কোনও লুপে রেজেেক্স চালানোর উদ্দেশ্যে (অর্থাত্ ফাইলের লাইন বাই লাইন পার্সিং) চালাতে চান তবে আপনার বিকল্প 2 দিয়ে যাওয়া উচিত।

আপনার যদি এমন অনেক রেজিওক্স থাকে যা আপনার অ্যাপ্লিকেশনটির জন্য কখনও বদলাবে না এবং তীব্রভাবে ব্যবহৃত হয়, আপনি বিকল্প 3 দিয়ে যেতে পারেন।


1
3 নং কাস্টম রসলিনের মাধ্যমে সহজ করা যায়CompileModule । অভি, আমাকে নতুন প্ল্যাটফর্মের আরও গভীরতর নজর দেওয়া দরকার।
খ্রিস্টান গোলহার্ড 18

9

এটি লক্ষ করা উচিত যে .NET 2.0 থেকে নিয়মিত এক্সপ্রেশনগুলির পারফরম্যান্স অসম্পূর্ণ নিয়মিত এক্সপ্রেশনগুলির একটি এমআরইউ ক্যাশে উন্নত হয়েছে। রেজেক্স লাইব্রেরি কোডটি আর প্রতিবার একই অ-সংকলিত নিয়মিত অভিব্যক্তিটির পুনরায় ব্যাখ্যা করে না।

সুতরাং সম্ভাব্যভাবে আরও বড় পারফরম্যান্স পেনাল্টি রয়েছে একটি সংকলিত এবং ফ্লাইতে নিয়মিত প্রকাশের সাথে আরও রয়েছে। ধীর লোডের সময় ছাড়াও, সিস্টেমটি ওপকডগুলিতে নিয়মিত এক্সপ্রেশনকে সংকলন করতে আরও মেমরি ব্যবহার করে।

মূলত, বর্তমান পরামর্শটি হয় নিয়মিত অভিব্যক্তিটি সংকলন করবেন না, বা পৃথক সমাবেশে আগাম সংকলন করবেন না।

রেফ: বিসিএল টিম ব্লগ নিয়মিত এক্সপ্রেশন পারফরম্যান্স [ডেভিড গুতেরেজ]



0

আমি আশা করি নীচের কোডটি আপনাকে re.compile ফাংশনগুলির ধারণাটি বুঝতে সহায়তা করবে

import re

x="""101 COM    Computers
205 MAT   Mathematics
189 ENG   English
222 SCI Science
333 TA  Tamil
5555 KA  Kannada
6666  TL  Telugu
777777 FR French
"""

#compile reg expression / successfully compiled regex can be used in any regex 
#functions    
find_subject_code=re.compile("\d+",re.M)
#using compiled regex in regex function way - 1
out=find_subject_code.findall(x)
print(out)
#using compiled regex in regex function way - 2
out=re.findall(find_numbers,x)
print(out)

#few more eg:
#find subject name
find_subjectnames=re.compile("(\w+$)",re.M) 
out=find_subjectnames.findall(x)
print(out)


#find subject SHORT name
find_subject_short_names=re.compile("[A-Z]{2,3}",re.M) 
out=find_subject_short_names.findall(x)
print(out)

আপনার উত্তরের জন্য ধন্যবাদ তবে আপনার কোডটি পাইথন ভাষায়। প্রশ্নটি ছিল মাইক্রোসফ্ট .NET ফ্রেমওয়ার্ক RegexOptions.Compiled বিকল্প সম্পর্কে। আপনি প্রশ্নের নীচে সংযুক্ত [[ নেট ] ট্যাগ দেখতে পারেন ।
stomy 5'19

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