চেষ্টা শেষ পর্যন্ত ব্যয়বহুল


14

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

  1. রিটার্নের প্রতিটি বিবৃতি দেওয়ার আগে সংস্থানটি পরিষ্কার করা

    void func()
    {
        login();
    
        bool ret = dosomething();
        if(ret == false)
        {
            logout();
            return;
        }
    
        ret = dosomethingelse();
        if(ret == false)
        {
            logout();
            return;
        }
    
        dootherstuff();
    
        logout();
    }
    
  2. শেষ অবধি রিসোর্সটি পরিষ্কার করা

    void func()
    {
        login();
    
        try
        {
            bool ret = dosomething();
            if(ret == false)
                return;
    
            ret = dosomethingelse();
            if(ret == false)
                return;
    
            dootherstuff();
    
        }
        finally
        {
            logout();
        }
    }
    

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


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

1
@ জনাথনরিচ: কীভাবে?
হাইলেম

2
কোডটি পরিষ্কারভাবে লিখুন যাতে আপনি যেটি সম্পাদনের চেষ্টা করছেন তা তা প্রকাশ করে। আপনি যখন বুঝতে পারেন যে আপনার কোনও সমস্যা আছে তখনই অনুকূলিত হন - ভাষার বৈশিষ্ট্যগুলি এড়িয়ে চলবেন না কারণ আপনি মনে করেন যে আপনি প্রথম স্থানে ধীরগতিতে কিছুটা দূরে কিছু মিলিসেকেন্ড শেভ করতে পারেন।
শন ম্যাকসোমিংথ

@ মিমি দ্য লিয়ার - আপনি যদি বলতে চান যে আমার লেখা উচিত if(!cond), তবে এটি জাভা যা আমাকে এটি করতে বাধ্য করেছিল। সি ++ তে, আমি উভয় বুলেটিয়ান এবং অন্য ধরণের জন্য কোড লিখি - যেমন int x; if(!x)। যেহেতু জাভা আমাকে কেবল এটির জন্য ব্যবহার করতে দেয় booleans, তাই আমি জাবা if(cond)& if(!cond)তে সম্পূর্ণভাবে ব্যবহার বন্ধ করে দিয়েছি ।
user93353

1
@ user93353 যা আমাকে দু: খিত করে। আমি (someIntValue != 0)বুলেঁদের মূল্যায়ন না করে তুলনা করার চেয়ে বরং দেখতে চাই । এটি আমার কাছে দুর্গন্ধযুক্ত এবং আমি বন্যের মধ্যে এটি দেখতে পেয়ে সঙ্গে সঙ্গে এটিকে পুনরায় চুল্লী করি।
মাইক দ্য লাইয়ার

উত্তর:


23

জাভা ব্যতিক্রমগুলি কত ধীরে ধীরে নির্দেশিত হয়েছে ? কেউ দেখতে পাবে যে এর try {} catch {}অস্তিত্ব ব্যতিক্রমের তাত্ক্ষণিকতার মধ্যে রয়েছে।

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

এই প্রশ্নে দেওয়া উদাহরণে কোনও ব্যতিক্রম নেই, কেউ এগুলি তৈরির ক্ষেত্রে কোনও ধীরগতির আশা করবেন না - সেগুলি তৈরি হয় না। পরিবর্তে, এখানে যা আছে তা হ'ল try {} finally {}শেষ অবধি ব্লকের মধ্যে রিসোর্স অবলম্বন পরিচালনা করতে।

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


যেমনটি উল্লেখ করা হয়েছে, রক্ষণাবেক্ষণ উভয় ক্ষেত্রে এটি করার একটি যুক্তি । রেকর্ডের জন্য, বিবেচনা করার পরে, আমার পছন্দটি শেষ অবধি হবে।

কাউকে একটি নতুন ভাষার কাঠামো শেখানোর রক্ষণাবেক্ষণের সময় বিবেচনা করুন। দেখতে দেখতে try {} finally {}এমন কিছু বিষয় যা এক প্রায়ই জাভা কোডে দেখেন এবং এইভাবে লোকদের বিভ্রান্তিকর হতে পারে না। লোকেরা যা দেখার সাথে পরিচিত তার চেয়ে জাভাতে কিছুটা আরও উন্নত কাঠামো শেখার জন্য একটি ডিগ্রি রক্ষণাবেক্ষণের সময় রয়েছে।

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

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

প্রথমে রক্ষণাবেক্ষণযোগ্য কোডটি লিখুন এবং পছন্দমত এমন পদ্ধতিতে যা বাগগুলি পরে লেখা থেকে রোধ করবে prevent


1
অ্যান-প্রস্তাবিত সম্পাদনাটি এভাবে বলেছে: "চেষ্টা করুন / অবশেষে গ্যারান্টি দেয় যে রানটাইম ব্যতিক্রম সম্পর্কিত অন্যথায় আপনার কোনও দরকার নেই you আপনি এটি পছন্দ করেন বা না চান, কোনও লাইনই একটি ব্যতিক্রম ছুঁড়তে কার্যত সক্ষম" - আমি: যা একেবারেই সত্য নয় । প্রশ্নে প্রদত্ত কাঠামোর কোনও অতিরিক্ত ব্যতিক্রম নেই যা কোডটির কার্য সম্পাদনকে ধীর করবে। অ-চেষ্টা / অবশেষে ব্লকের তুলনায় ব্লকটির চারপাশে চেষ্টা করে / শেষ পর্যন্ত মোড়ানো দ্বারা কোনও অতিরিক্ত কর্মক্ষমতা প্রভাব নেই acts

2
পরিশেষে চেষ্টা ব্যবহারের বোঝার চেয়ে রক্ষণাবেক্ষণের চেয়ে আরও ব্যয়বহুল আর কী হতে পারে, বেশ কয়েকটি ক্লিন-আপ ব্লক বজায় রাখতে হয়। এখন অন্তত আপনি জানেন যে অতিরিক্ত পরিষ্কার-পরিচ্ছন্নতার প্রয়োজন হলে এটি রাখার জন্য কেবলমাত্র একটি জায়গা রয়েছে।
বার্ট ভ্যান ইনজেন শেেনা

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

আমি প্রায়শই এটি জানাতে চেয়েছিলাম যে শেষ পর্যন্ত চেষ্টা করার বিকল্পটি বিনামূল্যে নয় isn't আমি আশা করি ব্যয়গুলি সম্পর্কে আপনার সংযোজনের জন্য আমি আরও একটি উত্সাহ দিতে পারতাম।
বার্ট ভ্যান ইনজেন শেনৌ

5

/programming/299068/how-slow-are-java-exceptions

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


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

1
ব্যতিক্রমগুলি অনুশীলনের ক্ষেত্রে অগত্যা বিরল নয়, এটি কেবল দুর্ঘটনাজনক পার্শ্ব প্রতিক্রিয়া। উদাহরণস্বরূপ, আপনার যদি খারাপ UI থাকে তবে সাধারণ প্রবাহের চেয়ে ব্যতিক্রম ব্যবহারের ক্ষেত্রে প্রবাহের কারণ হতে পারে
Esailija

2
প্রশ্নের কোডটিতে কোনও ব্যতিক্রম ছোঁড়া হচ্ছে না।

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

@ স্টোনমেটাল কী পাইরনের সাথে পাইথন ডিকের মতো
ইজকাটা

4

অনুকূলকরণের পরিবর্তে - আপনার কোডটি কী করছে তা ভেবে দেখুন।

শেষ অবধি ব্লক যুক্ত করা একটি ভিন্ন বাস্তবায়ন - এর অর্থ হ'ল আপনি প্রতিটি ব্যতিক্রম লগআউট করবেন।

বিশেষত - লগইন যদি ব্যতিক্রম ছুঁড়ে ফেলে তবে আপনার দ্বিতীয় ক্রিয়াকলাপের আচরণটি আপনার প্রথমটির চেয়ে আলাদা হবে।

লগইন এবং লগআউট যদি আসলে ফাংশন আচরণের অংশ না হয় তবে আমি পরামর্শ দেব যে পদ্ধতিতে একটি জিনিস এবং একটি জিনিস ভালভাবে করা উচিত:

    void func()
    {
            bool ret = dosomething();
            if(ret == false)
                return;

            ret = dosomethingelse();
            if(ret == false)
                return;

            dootherstuff();

    }

এবং এমন কোনও ফাংশনে থাকা উচিত যা ইতিমধ্যে একটি প্রসঙ্গে আবশ্যক যা লগইন / লগআউট পরিচালনা করে কারণ এগুলি আপনার মূল কোডটি যা করছে তার থেকে মৌলিকভাবে পৃথক বলে মনে হচ্ছে।

আপনার পোস্টটি জাভা হিসাবে ট্যাগ করা হয়েছে যার সাথে আমি খুব বেশি পরিচিত নই তবে আমি এটির জন্য একটি ব্লক ব্যবহার করব:

অর্থাৎ,

    using(var loginContext = CreateLoginContext()) 
    {
            // Do all your stuff
    }

এবং লগইন প্রসঙ্গে একটি নিষ্পত্তি পদ্ধতি রয়েছে যা লগআউট এবং সংস্থানগুলি পরিষ্কার করবে।

সম্পাদনা: আমি আসলে প্রশ্নের উত্তর দিলাম না!

আমার কাছে কোনও পরিমাপযোগ্য প্রমাণ নেই তবে আমি আশা করব না যে এটি কোনও আরও ব্যয়বহুল হবে বা এটি অকাল অপটিমাইজেশনের উপযুক্ত হওয়ার জন্য অবশ্যই যথেষ্ট ব্যয়বহুল নয়।

আমি আমার বাকী উত্তরটি ছেড়ে যাচ্ছি কারণ প্রশ্নের উত্তর না দিলেও, আমি মনে করি এটি অপের পক্ষে সহায়ক।


1
আপনার উত্তরটি সম্পূর্ণ করার জন্য জাভা 7 একটি চেষ্টা-সহ-সংস্থানসমূহের বিবৃতি প্রবর্তন করে যা আপনার। নেট usingনির্মাণের অনুরূপ , ধরে নেওয়া হয় যে প্রশ্নে থাকা সংস্থানটি AutoCloseableইন্টারফেস প্রয়োগ করে ।
হাইলেম

এমনকি আমি এই retভেরিয়েবলটিও সরিয়ে ফেলব , যা পরে একবারে এক লাইনে চেক করার জন্য দু'বার বরাদ্দ করা হয়েছে। এটি তৈরি করুন if (dosomething() == false) return;
ott--

সম্মত তবে আমি ওপি কোডটি যেভাবে সরবরাহ করা হয়েছিল তা রাখতে চাইছি।
মাইকেল 15

@ অট-- আমি ধরে নিলাম যে ওপির কোডটি তাদের ব্যবহারের কেসটির সরলীকরণ - উদাহরণস্বরূপ, তাদের আরও কিছু পছন্দ থাকতে পারে ret2 = doSomethingElse(ret1)তবে এটি প্রশ্নের সাথে প্রাসঙ্গিক নয় তাই এটি সরানো হয়েছে।
ইজকাটা

if (dosomething() == false) ...খারাপ কোড। আরও নিবিড়ভাবে ব্যবহার করুনif (!dosomething()) ...
স্টিফেন হিল

1

অনুমান: আপনি সি # কোডে বিকাশ করছেন।

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

দীর্ঘতর উত্তরটি আপনার নিজের জন্য দেখুন। আপনি যদি উত্পাদিত অন্তর্নিহিত সিআইএল কোডটি লক্ষ্য করেন ( উদাহরণস্বরূপ লাল গেট প্রতিফলক) তবে আপনি অন্তর্নিহিত সিআইএল নির্দেশাবলী উত্পন্ন করতে পারেন এবং সেইভাবে প্রভাবটি দেখতে পারেন।


11
প্রশ্নটি ট্যাগ করা জাভা
জোছিম সউর

ভাল বিক্ষোভ! ;)
মাইকেল শ

3
এছাড়াও, পদ্ধতিগুলি মূলধনযুক্ত নয়, যদিও এটি কেবল ভাল স্বাদ হতে পারে।
এরিক রেপেন

প্রশ্নটি সি # :) থাকলে এখনও একটি ভাল উত্তর
ফিলিএনজে

-2

অন্যরা ইতিমধ্যে উল্লিখিত হিসাবে, টিটিস কোডের পৃথক ফলাফল থাকবে, যদি হয় dosomethingelseবা dootherstuffব্যতিক্রম ছুঁড়ে ফেলে।

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


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