ব্যতিক্রমগুলি ছুঁড়ে দেওয়া না হলে ব্লকগুলি আঘাতের পারফরম্যান্সের চেষ্টা / ধরার চেষ্টা করে?


274

একটি মাইক্রোসফ্ট কর্মচারীর সাথে কোড পর্যালোচনা চলাকালীন আমরা একটি try{}ব্লকের অভ্যন্তরে কোডের একটি বিশাল অংশ জুড়ে এসেছি । তিনি এবং একজন আইটি প্রতিনিধি পরামর্শ দিয়েছিলেন যে কোডটির পারফরম্যান্সে এর প্রভাব থাকতে পারে। প্রকৃতপক্ষে, তারা পরামর্শ দিয়েছিল যে বেশিরভাগ কোড চেষ্টা / ধরার ব্লকের বাইরে থাকা উচিত এবং কেবলমাত্র গুরুত্বপূর্ণ বিভাগগুলি পরীক্ষা করা উচিত। মাইক্রোসফ্ট কর্মচারী যোগ করেছে এবং বলেছে যে একটি আসন্ন সাদা কাগজ ভুল চেষ্টা / ধরা ব্লক বিরুদ্ধে সতর্ক করে ns

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

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

ব্যতিক্রমগুলি ছুঁড়ে না দেওয়া হলে কীভাবে চেষ্টা / ধরা ব্লকগুলি কার্য সম্পাদনকে প্রভাবিত করে ?


147
"যে পারফরম্যান্সের জন্য নির্ভুলতা ত্যাগ করবে সেও প্রাপ্য নয়।"
জোয়েল কোহোর্ন

16
যে বলেছে যে, পারফরম্যান্সের জন্য সর্বদা নির্ভুলতা ত্যাগ করতে হবে না।
ড্যান ডেভিস ব্র্যাকেট

19
কীভাবে সহজ কৌতূহল?
সামান্থা ব্রানহাম

63
@ জোয়েল: সম্ভবত কোবি কৌতূহলের বাইরে উত্তর জানতে চেয়েছেন। পারফরম্যান্স আরও ভাল বা খারাপ হবে কিনা তা জানার অর্থ এই নয় যে সে তার কোডটি দিয়ে পাগল কিছু করতে যাচ্ছে। নিজের স্বার্থের জন্য জ্ঞানের সাধনা কি ভাল জিনিস নয়?
লুক 18

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

উত্তর:


203

এটি পরীক্ষা করে দেখুন।

static public void Main(string[] args)
{
    Stopwatch w = new Stopwatch();
    double d = 0;

    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        try
        {
            d = Math.Sin(1);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

    w.Stop();
    Console.WriteLine(w.Elapsed);
    w.Reset();
    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        d = Math.Sin(1);
    }

    w.Stop();
    Console.WriteLine(w.Elapsed);
}

আউটপুট:

00:00:00.4269033  // with try/catch
00:00:00.4260383  // without.

মিলিসেকেন্ডে:

449
416

নতুন কোড:

for (int j = 0; j < 10; j++)
{
    Stopwatch w = new Stopwatch();
    double d = 0;
    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        try
        {
            d = Math.Sin(d);
        }

        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        finally
        {
            d = Math.Sin(d);
        }
    }

    w.Stop();
    Console.Write("   try/catch/finally: ");
    Console.WriteLine(w.ElapsedMilliseconds);
    w.Reset();
    d = 0;
    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        d = Math.Sin(d);
        d = Math.Sin(d);
    }

    w.Stop();
    Console.Write("No try/catch/finally: ");
    Console.WriteLine(w.ElapsedMilliseconds);
    Console.WriteLine();
}

নতুন ফলাফল:

   try/catch/finally: 382
No try/catch/finally: 332

   try/catch/finally: 375
No try/catch/finally: 332

   try/catch/finally: 376
No try/catch/finally: 333

   try/catch/finally: 375
No try/catch/finally: 330

   try/catch/finally: 373
No try/catch/finally: 329

   try/catch/finally: 373
No try/catch/finally: 330

   try/catch/finally: 373
No try/catch/finally: 352

   try/catch/finally: 374
No try/catch/finally: 331

   try/catch/finally: 380
No try/catch/finally: 329

   try/catch/finally: 374
No try/catch/finally: 334

24
আপনি কি বিপরীত ক্রমে তাদের চেষ্টা করে দেখতে পারেন যে জেআইটি সংকলনের প্রাক্তনটির উপর কোনও প্রভাব পড়ে নি?
জোশ জোর্দান

28
এই জাতীয় প্রোগ্রামগুলি ব্যতিক্রম হ্যান্ডলিংয়ের প্রভাব পরীক্ষা করার জন্য ভাল প্রার্থীদের মতো মনে হয় না, সাধারণ চেষ্টা}} ক্যাচ}} ব্লকগুলি কী হবে তা অপ্টিমাইজ হতে চলেছে of আমি তার মধ্যাহ্নভোজনে বাইরে থাকতে পারি ...
লরেনভিএস

30
এটি একটি ডিবাগ বিল্ড। জেআইটি তাদের অনুকূলিত করে না।
বেন এম

7
এটি মোটেই সত্য নয়, এটি ভেবে দেখুন। আপনি কতবার একটি লুপ ধরার চেষ্টা করেন? বেশিরভাগ সময়ে আপনি যদি একটি try.c লুপ ব্যবহার করবে
Athiwat Chunlakhan

9
সত্যি? "ব্যতিক্রম ছুঁড়ে না দেওয়া হলে কীভাবে চেষ্টা / ধরা ব্লকগুলি কার্য সম্পাদনকে প্রভাবিত করে?"
বেন এম

105

চেষ্টা / ধরা এবং চেষ্টা / ধরা ছাড়াই সমস্ত স্ট্যাটাস দেখার পরে, কৌতূহল আমাকে উভয় ক্ষেত্রেই কী উত্পন্ন হয় তা দেখার জন্য পিছনে তাকাতে বাধ্য করেছিল। কোডটি এখানে:

সি #:

private static void TestWithoutTryCatch(){
    Console.WriteLine("SIN(1) = {0} - No Try/Catch", Math.Sin(1)); 
}

MSIL:

.method private hidebysig static void  TestWithoutTryCatch() cil managed
{
  // Code size       32 (0x20)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "SIN(1) = {0} - No Try/Catch"
  IL_0006:  ldc.r8     1.
  IL_000f:  call       float64 [mscorlib]System.Math::Sin(float64)
  IL_0014:  box        [mscorlib]System.Double
  IL_0019:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                object)
  IL_001e:  nop
  IL_001f:  ret
} // end of method Program::TestWithoutTryCatch

সি #:

private static void TestWithTryCatch(){
    try{
        Console.WriteLine("SIN(1) = {0}", Math.Sin(1)); 
    }
    catch (Exception ex){
        Console.WriteLine(ex);
    }
}

MSIL:

.method private hidebysig static void  TestWithTryCatch() cil managed
{
  // Code size       49 (0x31)
  .maxstack  2
  .locals init ([0] class [mscorlib]System.Exception ex)
  IL_0000:  nop
  .try
  {
    IL_0001:  nop
    IL_0002:  ldstr      "SIN(1) = {0}"
    IL_0007:  ldc.r8     1.
    IL_0010:  call       float64 [mscorlib]System.Math::Sin(float64)
    IL_0015:  box        [mscorlib]System.Double
    IL_001a:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                  object)
    IL_001f:  nop
    IL_0020:  nop
    IL_0021:  leave.s    IL_002f //JUMP IF NO EXCEPTION
  }  // end .try
  catch [mscorlib]System.Exception 
  {
    IL_0023:  stloc.0
    IL_0024:  nop
    IL_0025:  ldloc.0
    IL_0026:  call       void [mscorlib]System.Console::WriteLine(object)
    IL_002b:  nop
    IL_002c:  nop
    IL_002d:  leave.s    IL_002f
  }  // end handler
  IL_002f:  nop
  IL_0030:  ret
} // end of method Program::TestWithTryCatch

আমি আইএল-তে কোনও বিশেষজ্ঞ নই তবে আমরা দেখতে পাচ্ছি যে চতুর্থ লাইনে একটি স্থানীয় ব্যতিক্রম বস্তু তৈরি .locals init ([0] class [mscorlib]System.Exception ex)হয়ে গেছে তার পরে জিনিসটি চেষ্টা / ধরার ছাড়াই লাইন সতেরো অবধি পদ্ধতি অনুসারে প্রায় একই রকম IL_0021: leave.s IL_002f। যদি কোনও ব্যতিক্রম ঘটে থাকে তবে নিয়ন্ত্রণটি লাফাতে IL_0025: ldloc.0লাফায় অন্যথায় আমরা লেবেল IL_002d: leave.s IL_002fএবং ফাংশন রিটার্নে ঝাঁপ দাও ।

আমি নিরাপদে ধরে নিতে পারি যে যদি কোনও ব্যতিক্রম না ঘটে তবে কেবল ব্যতিক্রমী অবজেক্টগুলি রাখা এবং জাম্পের নির্দেশ দেওয়ার জন্য এটি স্থানীয় ভেরিয়েবলগুলি তৈরির ওভারহেড ।


33
ঠিক আছে, আইএলটিতে সি # এর মতো একই স্বরলিপিতে একটি ট্রাই / ক্যাচ ব্লক অন্তর্ভুক্ত রয়েছে, সুতরাং এটি সত্যিই দেখায় না যে পর্দার আড়ালে একটি ট্রাই / ক্যাচ কতটা ওভারহেড বোঝায়! যেহেতু আইএল আরও বেশি কিছু যোগ করে না, এটি একইভাবে বোঝায় না কারণ এটি সংকলিত সমাবেশ কোডটিতে কিছু যুক্ত করা হয়নি। আইএল হ'ল সমস্ত নেট ভাষাগুলির একটি সাধারণ প্রতিনিধিত্ব। এটি মেশিনের কোড নয়!
ভয়

64

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


10
এটি একটি দুর্দান্ত পয়েন্ট - আমাদের তালিকার অন্যান্য আইটেমগুলির সাথে তুলনা করুন, এটি একটি সংক্ষিপ্ত হওয়া উচিত। সঠিকভাবে আচরণ করার জন্য আমাদের মৌলিক ভাষার বৈশিষ্ট্যগুলিতে বিশ্বাস করা উচিত এবং আমরা কীভাবে নিয়ন্ত্রণ করতে পারি তা অপ্টিমাইজ করতে হবে (বর্গ, সূচী, অ্যালগোরিদম)।
কোবি

3
টাইট লুপস সাথীর কথা ভাবেন। গেম সার্ভারে সকেট ডেটা স্ট্রিম এবং আপনি যতটা পারেন ততটুকু নিচু করার চেষ্টা করছেন এমন লুপের উদাহরণটি যেখানে আপনি পড়েন এবং ডি-সিরিয়ালাইজ করুন। সুতরাং আপনি বাইনারি ফর্ম্টারের পরিবর্তে অবজেক্ট সিরিয়ালাইজেশনের জন্য মেসেজপ্যাক করুন এবং কেবল বাইট অ্যারে ইত্যাদি তৈরির পরিবর্তে অ্যারেপুল <বাইট> ব্যবহার করুন ... এই পরিস্থিতিতে দৃari় লুপের মধ্যে একাধিক (সম্ভবত নেস্টেড) ব্লক ধরার চেষ্টা কী what কিছু অপ্টিমাইজেশানগুলি সংকলক দ্বারা এড়িয়ে যাবে এছাড়াও ব্যতিক্রম ভেরিয়েবল জেন 0 জিসিতে যায়। আমি যা বলছি তা হ'ল "কিছু" পরিস্থিতি রয়েছে যেখানে সমস্ত কিছুই প্রভাবিত হয়।
tcwicks

35

। নেট ব্যতিক্রম মডেলটির বেশ বিস্তৃত ব্যাখ্যা।

রিকো মারিয়ানির পারফরম্যান্স টিডিবিটস: ব্যতিক্রম ব্যয়: কখন ফেলবেন এবং কখন করবেন না

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

দিমিত্রি জাসলভস্কি:

ক্রিস ব্রুমের নোট অনুসারে: জেআইটি কর্তৃক ক্যাচর উপস্থিতিতে কিছু অপ্টিমাইজেশন করা হচ্ছে না এই বিষয়টি সম্পর্কিত একটি ব্যয়ও রয়েছে catch


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

রিকো মারিয়ানির দাবি দেশীয় সি ++ এর জন্য সম্পূর্ণ ভুল। "স্ট্যাটিক ব্যয় সি ++ বলার চেয়ে অনেক কম হতে পারে" - এটি কেবল সত্য নয়। যদিও, আমি নিশ্চিত নই যে ২০০৩ সালে যখন নিবন্ধটি লেখা হয়েছিল তখন ব্যতিক্রম প্রক্রিয়াটির নকশাটি কী ছিল। আপনার যতগুলি চেষ্টা / ক্যাচ ব্লক আছে এবং সেগুলি যেখানেই থাকুক না কেন, ব্যতিক্রম ছুঁড়ে ফেলা না হলে সি ++ এর আসলে কোনও মূল্য নেই
বিজেভকে

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

24

কাঠামোটি বেন এম থেকে উদাহরণে পৃথক । এটি অভ্যন্তরীণ forলুপের অভ্যন্তরে ওভারহেড প্রসারিত হবে যা এটি দুটি ক্ষেত্রে মধ্যে ভাল তুলনা না করতে পারে।

ট্রাই / ক্যাচ ব্লকের ভিতরে পুরো কোডটি (ভেরিয়েবল ডিক্লেয়ারেশন সহ) পরীক্ষা করার জন্য নীচের তুলনা করার জন্য আরও সঠিক:

        for (int j = 0; j < 10; j++)
        {
            Stopwatch w = new Stopwatch();
            w.Start();
            try { 
                double d1 = 0; 
                for (int i = 0; i < 10000000; i++) { 
                    d1 = Math.Sin(d1);
                    d1 = Math.Sin(d1); 
                } 
            }
            catch (Exception ex) {
                Console.WriteLine(ex.ToString()); 
            }
            finally { 
                //d1 = Math.Sin(d1); 
            }
            w.Stop(); 
            Console.Write("   try/catch/finally: "); 
            Console.WriteLine(w.ElapsedMilliseconds); 
            w.Reset(); 
            w.Start(); 
            double d2 = 0; 
            for (int i = 0; i < 10000000; i++) { 
                d2 = Math.Sin(d2);
                d2 = Math.Sin(d2); 
            } 
            w.Stop(); 
            Console.Write("No try/catch/finally: "); 
            Console.WriteLine(w.ElapsedMilliseconds); 
            Console.WriteLine();
        }

আমি যখন বেন এম থেকে মূল পরীক্ষার কোডটি চালিয়েছি তখন আমি ডিবাগ এবং রিলিজ কনফিগারেশনের উভয় ক্ষেত্রেই একটি পার্থক্য লক্ষ্য করেছি।

এই সংস্করণে, আমি ডিবাগ সংস্করণে পার্থক্য লক্ষ্য করেছি (অন্য সংস্করণের তুলনায় আসলে) তবে এটি প্রকাশ সংস্করণে কোনও পার্থক্য ছিল না।

Conclution :
এই পরীক্ষা উপর ভিত্তি করে, আমি মনে করি আমরা বলতে পারি যে চেষ্টা / ক্যাচ করে কর্মক্ষমতার উপর একটি ছোট প্রভাব আছে।

সম্পাদনা:
আমি লুপের মান 10000000 থেকে 1000000000 এ বাড়ানোর চেষ্টা করেছি, এবং রিলিজে কিছুটা পার্থক্য পেতে আবার দৌড়ে এসেছি এবং ফলাফলটি ছিল:

   try/catch/finally: 509
No try/catch/finally: 486

   try/catch/finally: 479
No try/catch/finally: 511

   try/catch/finally: 475
No try/catch/finally: 477

   try/catch/finally: 477
No try/catch/finally: 475

   try/catch/finally: 475
No try/catch/finally: 476

   try/catch/finally: 477
No try/catch/finally: 474

   try/catch/finally: 475
No try/catch/finally: 475

   try/catch/finally: 476
No try/catch/finally: 476

   try/catch/finally: 475
No try/catch/finally: 476

   try/catch/finally: 475
No try/catch/finally: 474

আপনি দেখতে পাচ্ছেন যে ফলাফলটি অসংলগ্ন। কিছু ক্ষেত্রে ট্রাই / ক্যাচ ব্যবহার করে সংস্করণটি আসলে দ্রুততর হয়!


1
আমি এটিও লক্ষ্য করেছি, কখনও কখনও চেষ্টা / ধরার সাথে এটি দ্রুত। বেনের উত্তরে আমি এটি মন্তব্য করেছি। তবে, ২৪ জন ভোটারের বিপরীতে, আমি এই ধরণের বেঞ্চমার্কিং পছন্দ করি না, আমি মনে করি এটি একটি ভাল ইঙ্গিত নয়। এই ক্ষেত্রে কোডটি দ্রুততর তবে এটি কি সর্বদা থাকবে?
কোবি

5
এটি কি প্রমাণ করে না যে আপনার মেশিন একই সাথে অন্যান্য বিভিন্ন কাজ করছিল? অতিবাহিত সময় কখনও ভাল পরিমাপ হয় না, আপনাকে এমন একটি প্রোফাইলার ব্যবহার করতে হবে যা প্রসেসরের সময় রেকর্ড করে, সময় অতিবাহিত হয় না।
কলিন ডেসমন্ড

2
@ কোবি: আমি সম্মত হই যে আপনার প্রোগ্রামটি অন্য বা যে কোনও কিছুর চেয়ে দ্রুত গতিতে চলেছে এই প্রমাণ হিসাবে আপনি এটি প্রকাশ করতে গেলে বেঞ্চমার্কের পক্ষে এটি সর্বোত্তম উপায় নয়, তবে আপনাকে একজন বিকাশকারী হিসাবে অন্য পদ্ধতির চেয়ে আরও ভাল পারফরম্যান্স সম্পাদনের ইঙ্গিত দিতে পারেন । এই ক্ষেত্রে, আমি মনে করি আমরা বলতে পারি যে পার্থক্যগুলি (কমপক্ষে রিলিজ কনফিগারেশনের জন্য) উপেক্ষাযোগ্য।
অবাক

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

15

আমি try..catchএকটি আঁট লুপটিতে একটি এর প্রকৃত প্রভাবটি পরীক্ষা করেছি এবং এটি কোনও সাধারণ পরিস্থিতিতে পারফরম্যান্স উদ্বেগ হওয়ার পক্ষে এটি খুব ছোট।

যদি লুপটি খুব কম কাজ করে (আমার পরীক্ষায় আমি একটি করেছিলাম) x++ ) তবে আপনি ব্যতিক্রম হ্যান্ডলিংয়ের প্রভাব পরিমাপ করতে পারেন। ব্যতিক্রম হ্যান্ডলিং সহ লুপটি চালাতে প্রায় দশগুণ বেশি সময় নিয়েছিল।

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


11

ক্যাপ ব্লকগুলি পারফরম্যান্সের উপর একটি নগণ্য প্রভাব ফেলতে পারে তবে ব্যতিক্রম নিক্ষেপ করা বেশ বড় আকারের হতে পারে, এটি সম্ভবত আপনার সহকর্মী বিভ্রান্ত হয়েছিল।


8

চেষ্টা / ধরার পারফরম্যান্সের উপর প্রভাব ফেলে।

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

চেষ্টা / ধরা কর্মক্ষমতা সম্পর্কে এখানে একটি রেফারেন্স দেওয়া হয়েছে (যদিও এর জটিলতাটি ব্যাখ্যা করে না তবে এটি বোঝানো হয়েছে)। কটাক্ষপাত নিক্ষেপ কম ব্যতিক্রমসমূহ অধ্যায়


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

6

তত্ত্ব অনুসারে, কোনও চেষ্টা / ক্যাচ ব্লকের কোড আচরণের উপর কোনও প্রভাব থাকবে না যদি না আসলে ব্যতিক্রম ঘটে occurs কিছু বিরল পরিস্থিতি রয়েছে, তবে যেখানে চেষ্টা / ধরার ব্লকের অস্তিত্বের একটি বড় প্রভাব থাকতে পারে এবং কিছু অস্বাভাবিক-তবে-কিন্তু-অস্পষ্ট বিষয় যেখানে প্রভাব লক্ষণীয় হতে পারে। এর কারণটি হল প্রদত্ত কোডের মতো:

Action q;
double thing1()
  { double total; for (int i=0; i<1000000; i++) total+=1.0/i; return total;}
double thing2()
  { q=null; return 1.0;}
...
x=thing1();     // statement1
x=thing2(x);    // statement2
doSomething(x); // statement3

সংকলক বিবৃতি 2 স্টেটমেন্ট 3 এর আগে কার্যকর করার গ্যারান্টিযুক্ত এই তথ্যের উপর ভিত্তি করে স্টেটমেন্ট 1 অনুকূল করতে সক্ষম হতে পারে। যদি সংকলকটি বুঝতে পারে যে জিনিস 1 এর কোনও পার্শ্ব প্রতিক্রিয়া নেই এবং জিনিস 2 আসলে এক্স ব্যবহার না করে তবে এটি নিরাপদে জিনিস 1 বাদ দিতে পারে। যদি [যেমন এই ক্ষেত্রে] জিনিস 1 ব্যয়বহুল ছিল, তবে এটি একটি বড় অপটিমাইজেশন হতে পারে, যদিও জিনিস 1 ব্যয়বহুল ক্ষেত্রেও সেগুলি সংকলকটি অপ্টিমাইজ হওয়ার সম্ভাবনা কম। ধরুন কোডটি পরিবর্তন করা হয়েছে:

x=thing1();      // statement1
try
{ x=thing2(x); } // statement2
catch { q(); }
doSomething(x);  // statement3

এখন ইভেন্টগুলির ক্রম রয়েছে যেখানে স্টেটমেন্ট 3 স্টেটমেন্ট 2 ছাড়াই কার্যকর করতে পারে exec কোডের কোনও কিছুর thing2ব্যতিক্রম ছুঁড়ে ফেলতে না পারলেও, অন্য থ্রেডটি পরিষ্কার হয়ে গেছে এবং এটি সেট করে Interlocked.CompareExchangeলক্ষ্য করাতে একটি ব্যবহার করতে পারে এবং তারপরে স্টেটমেন্ট 2 এর মান লিখার আগে একটি সম্পাদন করতে পারে । তারপরে স্টেটমেন্ট 3 দিয়ে মৃত্যুদন্ড কার্যকর করার অনুমতি দিয়ে [প্রতিনিধিদের মাধ্যমে ] মৃত্যুদণ্ড কার্যকর করা হত । এই জাতীয় ইভেন্টের ক্রম অবশ্যই ব্যতিক্রমী অসম্ভব, তবে এমন একটি সংকলক কোড তৈরি করতে হয় যা এই জাতীয় অসম্ভব ঘটনার পরেও স্পেসিফিকেশন অনুযায়ী কাজ করে।qThread.ResetAbortThread.Abort()xcatchThread.ResetAbort()q

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


5

যদিও " প্রতিরোধ ব্যবস্থাপনার চেয়ে ভাল ", পারফরম্যান্স এবং দক্ষতার দৃষ্টিকোণে আমরা প্রাক-বৈকল্পিকতার চেয়ে চেষ্টাটি বেছে নিতে পারি। নীচের কোডটি বিবেচনা করুন:

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 1; i < int.MaxValue; i++)
{
    if (i != 0)
    {
        int k = 10 / i;
    }
}
stopwatch.Stop();
Console.WriteLine($"With Checking: {stopwatch.ElapsedMilliseconds}");
stopwatch.Reset();
stopwatch.Start();
for (int i = 1; i < int.MaxValue; i++)
{
    try
    {
        int k = 10 / i;
    }
    catch (Exception)
    {

    }
}
stopwatch.Stop();
Console.WriteLine($"With Exception: {stopwatch.ElapsedMilliseconds}");

ফলাফল এখানে:

With Checking: 20367
With Exception: 13998

4

কীভাবে / ক্যাচ ব্লকগুলি কাজ করে এবং কীভাবে কোনও ব্যতিক্রম ঘটে না, যখন কিছু বাস্তবায়নের উচ্চ ওভারহেড থাকে এবং কিছুগুলির শূন্য ওভারহেড থাকে তার আলোচনার জন্য চেষ্টা / ক্যাচ বাস্তবায়নের উপর আলোচনা দেখুন । বিশেষত, আমি মনে করি উইন্ডোজ 32 বিট বাস্তবায়নের উচ্চ ওভারহেড রয়েছে, এবং 64 বিট বাস্তবায়ন নেই।


আমি যা বর্ণনা করেছি তা ব্যতিক্রম বাস্তবায়নের দুটি ভিন্ন পদ্ধতি। পদ্ধতিগুলি C ++ এবং C # তে একইভাবে পরিচালিত / নিয়ন্ত্রণহীন কোডের ক্ষেত্রেও সমানভাবে প্রযোজ্য। এমএস তাদের সি # এর জন্য কোনটি বেছে নিয়েছে আমি ঠিক জানি না, তবে এমএস দ্বারা সরবরাহ করা মেশিন-স্তরের অ্যাপ্লিকেশনগুলির ব্যতিক্রম-হ্যান্ডলিং আর্কিটেকচারটি দ্রুত স্কিম ব্যবহার করে। যদি আমি # বিটের জন্য # # বাস্তবায়ন এটি ব্যবহার না করে তবে আমি কিছুটা অবাক হব।
ইরা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.