যদি বিবৃতি - শর্ট সার্কিট মূল্যায়ন বনাম পাঠযোগ্যতা


90

কখনও কখনও, একটি ifবিবৃতি বরং জটিল বা দীর্ঘ হতে পারে, তাই পাঠযোগ্যতার খাতিরে এটির আগে জটিল কলগুলি উত্তোলন করা ভাল if

যেমন:

if (SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall())
{
    // do stuff
}

এই মধ্যে

bool b1 = SomeComplicatedFunctionCall();
bool b2 = OtherComplicatedFunctionCall();

if (b1 || b2)
{
    //do stuff
}

(প্রদত্ত উদাহরণ নয় যে , খারাপ এটা ঠিক চিত্রণ জন্য হয় ... একাধিক আর্গুমেন্ট, ইত্যাদি সঙ্গে অন্যান্য কলের কল্পনা)

তবে এই নিষ্কাশন দিয়ে আমি শর্ট সার্কিট মূল্যায়ন (এসসিই) হারাতে পেরেছি।

  1. আমি কি সত্যিই প্রতিবার এসসিই হারাতে পারি? এমন কোনও দৃশ্য আছে যেখানে সংকলকটিকে "এটি অনুকূলিতকরণ" এবং এখনও এসসিই সরবরাহ করার অনুমতি দেওয়া হয়েছে?
  2. এসসিই না হারিয়ে দ্বিতীয় স্নিপেটের উন্নত পাঠযোগ্যতা রাখার কী উপায় আছে?

20
অনুশীলনটি দেখায় যে কর্মক্ষমতা সম্পর্কে সর্বাধিক উত্তর আপনি এখানে বা অন্য জায়গাগুলিতে দেখতে পাবেন বেশিরভাগ ক্ষেত্রে ভুল (4 টি ভুল 1 সঠিক)। আমার পরামর্শটি সর্বদা একটি প্রোফাইল করা এবং এটি নিজে যাচাই করা, আপনি "অকাল অপ্টিমাইজেশন" এড়াতে এবং নতুন জিনিস শিখবেন।
মেরেক আর

25
@ মেরেকআর কেবল পারফরম্যান্সের জন্য নয়, এটি অন্যান্যড্রাকশনক্লায় সম্ভাব্য পার্শ্ব প্রতিক্রিয়া সম্পর্কে ...
শিথিল XXX

4
@David যখন অন্যান্য সাইট উল্লেখ, এটা যে প্রায়ই বিন্দু সহায়ক ক্রস-পোস্টিং উপর frowned হয়
মশা

7
পাঠযোগ্যতা যদি আপনার প্রাথমিক উদ্বেগ হয় তবে শর্তাধীন যদি কোনও অভ্যন্তরের পার্শ্ব প্রতিক্রিয়াযুক্ত ফাংশনগুলি কল করবেন না
মরজেন

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

উত্তর:


119

একটি প্রাকৃতিক সমাধান এর মত দেখতে হবে:

bool b1 = SomeCondition();
bool b2 = b1 || SomeOtherCondition();
bool b3 = b2 || SomeThirdCondition();
// any other condition
bool bn = bn_1 || SomeFinalCondition();

if (bn)
{
  // do stuff
}

এটি সহজেই বোঝার, সমস্ত ক্ষেত্রে প্রযোজ্য এবং শর্ট সার্কিট আচরণের সুবিধা রয়েছে।


এটি ছিল আমার প্রাথমিক সমাধান: পদ্ধতি কলগুলিতে এবং লুপের জন্য বডিগুলির জন্য একটি ভাল ধরণটি নিম্নলিখিত:

if (!SomeComplicatedFunctionCall())
   return; // or continue

if (!SomeOtherComplicatedFunctionCall())
   return; // or continue

// do stuff

শর্টকিট মূল্যায়নের ক্ষেত্রে দুর্দান্ত পারফরম্যান্সের জন্য একই সুবিধা পাওয়া যায় তবে কোডটি আরও পঠনযোগ্য বলে মনে হয়।


4
@ রিলএলএক্সএক্সএক্স: আমি পেয়েছি, তবে "এর পরে আরও কিছু করতে হবে if" এটিও একটি চিহ্ন যে আপনার ফাংশন বা পদ্ধতিটি খুব বড়, এবং এটি আরও ছোট আকারে বিভক্ত হওয়া উচিত। এটি সর্বদা সেরা উপায় না তবে খুব প্রায়ই হয়!
মাইক 3996

4
এটি সাদা তালিকা নীতির লঙ্ঘন করে
JulinRouge

13
@ জোলিনরুজ: মজার বিষয়, আমি এই নীতিটি কখনও শুনিনি। আমি নিজেই পঠনযোগ্যতার সুবিধাগুলির জন্য এই "শর্ট-সার্কিট" পদ্ধতির পছন্দ করি: এটি ইনডেন্টেশনগুলি হ্রাস করে এবং ইন্ডেন্টেড ব্লকের পরে কিছু হওয়ার সম্ভাবনাটি সরিয়ে দেয়।
ম্যাথিউ এম।

4
এটা কি আরও পঠনযোগ্য? নামটি b2সঠিকভাবে দিন এবং আপনি পেয়ে যাবেন someConditionAndSomeotherConditionIsTrue, অর্থপূর্ণ নয়। এছাড়াও, এই অনুশীলনের সময় আমাকে আমার মানসিক স্ট্যাকের একগুচ্ছ পরিবর্তনশীল রাখতে হবে (এবং আমি এই স্কোপটিতে কাজ করা বন্ধ না করা পর্যন্ত টিবিএইচ)। আমি SJuan762 নম্বর সমাধান নিয়ে যাব বা পুরো জিনিসটি কোনও ফাংশনে রেখে দেব ।
নাথান কুপার

4
আমি সমস্ত মন্তব্য পড়িনি তবে দ্রুত অনুসন্ধানের পরে আমি প্রথম কোড স্নিপেট যথা ডিবাগিংয়ের একটি বড় সুবিধা পাইনি। আগে-আগে কোনও ভেরিয়েবলকে বরাদ্দ করার পরিবর্তে স্টাফটি সরাসরি-আই-স্টেটে স্থাপন করা এবং তার পরিবর্তে ভেরিয়েবলটি ব্যবহার করা প্রয়োজনের চেয়ে ডিবাগিংকে আরও কঠিন করে তোলে। ভেরিয়েবলগুলি ব্যবহার করে শব্দ মূল্যবোধগুলি একসাথে একত্রিত করার অনুমতি দেয় যা পাঠযোগ্যতা বৃদ্ধি করে।
rbaleksandar

30

আমি শর্তগুলি একাধিক লাইনে বিভক্ত করে, যেমন:

if( SomeComplicatedFunctionCall()
 || OtherComplicatedFunctionCall()
  ) {

এমনকি একাধিক অপারেটর (&&) এর সাথে ডিল করার সময় আপনাকে কেবল প্রতিটি জোড়া বন্ধনী দিয়ে ইনডেনশন এগিয়ে নিতে হবে। এসসিই এখনও লিক করে - ভেরিয়েবলগুলি ব্যবহার করার দরকার নেই। কোড লেখার পদ্ধতিটি ইতিমধ্যে আমার কাছে বছরের পর বছর ধরে এটি আরও বেশি পাঠযোগ্য। আরও জটিল উদাহরণ:

if( one()
 ||( two()> 1337
  &&( three()== 'foo'
   || four()
    )
   )
 || five()!= 3.1415
  ) {

28

আপনার যদি শর্তগুলির দীর্ঘ শৃঙ্খলা থাকে এবং কিছু সংক্ষিপ্ত সংকেত কী রাখে, তবে আপনি একাধিক শর্ত একত্রিত করতে অস্থায়ী পরিবর্তনগুলি ব্যবহার করতে পারেন। আপনার উদাহরণটি গ্রহণ করা উদাহরণস্বরূপ করা সম্ভব হবে

bool b = SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall();
if (b && some_other_expression) { ... }

যদি আপনার কাছে সি ++ 11 সক্ষম সংকলক থাকে তবে আপনি ল্যাম্বডা এক্সপ্রেশনটি এক্সপ্রেশনগুলিকে ফাংশনগুলিতে সংযুক্ত করতে ব্যবহার করতে পারেন , উপরের মত:

auto e = []()
{
    return SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall();
};

if (e() && some_other_expression) { ... }

21

1) হ্যাঁ, আপনার আর এসসিই নেই। অন্যথায়, আপনি যে হবে

bool b1 = SomeComplicatedFunctionCall();
bool b2 = OtherComplicatedFunctionCall();

ifপরে কোনও বিবৃতি আছে কিনা তা নির্ভর করে একভাবে বা অন্যভাবে কাজ করে । উপায় খুব জটিল।

2) এটি মতামত ভিত্তিক, তবে যুক্তিযুক্ত জটিল ভাবের জন্য আপনি এটি করতে পারেন:

if (SomeComplicatedFunctionCall()
    || OtherComplicatedFunctionCall()) {

যদি এটি খুব জটিল হয়ে যায় তবে সুস্পষ্ট সমাধানটি হ'ল একটি ফাংশন তৈরি করা যা অভিব্যক্তিটির মূল্যায়ন করে এটি কল করে।


21

আপনি এটি ব্যবহার করতে পারেন:

bool b = someComplicatedStuff();
b = b || otherComplicatedStuff(); // it has to be: b = b || ...;  b |= ...; is bitwise OR and SCE is not working then 

এবং এসসিই কাজ করবে।

তবে এটি উদাহরণের চেয়ে বেশি পঠনযোগ্য নয়:

if (
    someComplicatedStuff()
    ||
    otherComplicatedStuff()
   )

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

4
আমি স্পষ্টতই ব্যবহার করেছি b = b || otherComplicatedStuff();এবং @ সার্জবার্স এসসিই অপসারণ করতে একটি সম্পাদনা করেছেন। @ পরিবর্তন সম্পর্কে আমাকে লক্ষ্য করার জন্য ধন্যবাদ।
KIIV

14

1) আমি কি সত্যিই প্রতিবার এসসিই হারাতে পারি? সংকলককে কি কিছু দৃশ্যের "এটি অনুকূলিতকরণ" করার অনুমতি দেওয়া এবং এখনও এসসিই সরবরাহ করার অনুমতি রয়েছে?

আমি মনে করি না যে এই ধরনের অপ্টিমাইজেশনের অনুমতি রয়েছে; বিশেষত OtherComplicatedFunctionCall()কিছু পার্শ্ব প্রতিক্রিয়া হতে পারে।

2) এই পরিস্থিতিতে সেরা অনুশীলন কি? যদি কেবল "ভিতরে এসইসিই চাই" তখনই কেবল আমার ভিতরে থাকা সমস্ত কি কেবল সম্ভব হয় এবং যদি "এটি যতটা সম্ভব পঠনযোগ্য হিসাবে ফর্ম্যাট করে"?

আমি এটিকে একটি ফাংশন বা বর্ণনামূলক নামের সাথে একটি ভেরিয়েবলে রিফ্যাক্টর করতে পছন্দ করি; যা শর্ট সার্কিট মূল্যায়ন এবং পাঠযোগ্যতা উভয়ই সংরক্ষণ করবে:

bool getSomeResult() {
    return SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall();
}

...

if (getSomeResult())
{
    //do stuff
}

এবং আমরা এর getSomeResult()উপর ভিত্তি করে বাস্তবায়ন করেছি SomeComplicatedFunctionCall()এবং OtherComplicatedFunctionCall()যদি তারা এখনও জটিল হয় তবে আমরা তাদের পুনরাবৃত্তভাবে পচন করতে পারি।


4
আমি এটি পছন্দ করি কারণ আপনি মোড়ক ফাংশনটিকে একটি বর্ণনামূলক নাম (যদিও সম্ভবত getSomeResult না পেয়ে) প্রদান করে কিছুটা পঠনযোগ্যতা অর্জন করতে পারেন, আরও অনেক উত্তর উত্তর সত্যই কোনও মূল্য যোগ করে না
aw04

9

1) আমি কি সত্যিই প্রতিবার এসসিই হারাতে পারি? সংকলককে কি কিছু দৃশ্যের "এটি অনুকূলিতকরণ" করার অনুমতি দেওয়া এবং এখনও এসসিই সরবরাহ করার অনুমতি রয়েছে?

না আপনি না, তবে এটি আলাদাভাবে প্রয়োগ করা হয়:

if (SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall())
{
    // do stuff
}

এখানে, সংকলকটি এমনকি OtherComplicatedFunctionCall()যদি SomeComplicatedFunctionCall()সত্যটি ফিরে আসে তবে চলবে না ।

bool b1 = SomeComplicatedFunctionCall();
bool b2 = OtherComplicatedFunctionCall();

if (b1 || b2)
{
    //do stuff
}

এখানে, উভয় কর্ম করবে চালানোর কারণ তারা মধ্যে সংরক্ষণ করা আছে b1এবং b2। Ff এর b1 == trueপরে b2মূল্যায়ন করা হবে না (এসসিই)। কিন্তুOtherComplicatedFunctionCall() ইতোমধ্যে চালানো হয়েছে।

যদি b2অন্য কোথাও ব্যবহার করা হয় তবে ফাংশনটির যদি কোন পর্যবেক্ষণযোগ্য পার্শ্ব-প্রতিক্রিয়া না থাকে তবে সংকলকটির ভিতরে ফাংশন কলটি ইনलाइन করার জন্য যথেষ্ট স্মার্ট হতে পারে।

2) এই পরিস্থিতিতে সেরা অনুশীলন কি? যদি কেবল "ভিতরে এসইসিই চাই" তখনই কেবল আমার ভিতরে থাকা সমস্ত কি কেবল সম্ভব হয় এবং যদি "এটি যতটা সম্ভব পঠনযোগ্য হিসাবে ফর্ম্যাট করে"?

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


8

শর্ট সার্কিট এবং এক জায়গায় শর্ত রয়েছে এমন আরেকটি সম্ভাবনা:

bool (* conditions [])()= {&a, &b, ...}; // list of conditions
bool conditionsHold = true;
for(int i= 0; i < sizeOf(conditions); i ++){
     if (!conditions[i]()){;
         conditionsHold = false;
         break;
     }
}
//conditionsHold is true if all conditions were met, otherwise false

আপনি কোনও ফাংশনে লুপটি রাখতে পারেন এবং ফাংশনটিকে শর্তগুলির একটি তালিকা গ্রহণ করতে দেয় এবং একটি বুলিয়ান মান দেয়।


4
পছন্দ করেছেন অ্যারের উপাদানগুলি হ'ল ফাংশন পয়েন্টার, লুপে ফাংশন না বলা পর্যন্ত এগুলি সম্পাদন করা হয় না।
বার্মার

ধন্যবাদ বার্মার, তবে আমি একটি সম্পাদনা করেছি, সম্পাদনার আগে এরবুর্থ ঠিকই ছিলেন (আমি ভেবেছিলাম আমার সম্পাদনা দৃশ্যত আরও সরাসরি প্রচার করবে) would
লেভিলাইমে

4

খুব আশ্চর্যজনক: আপনি যখনই কোডের মধ্যে মন্তব্য ব্যবহারের উল্লেখ না করে থাকেন তখন আপনি পঠনযোগ্যতার কথা বলছেন:

if (somecomplicated_function() || // let me explain what this function does
    someother_function())         // this function does something else
...

সর্বোপরি, আমি সবসময় কিছু ফাংশন সম্পর্কে, নিজের ফাংশনটি সম্পর্কে, এর ইনপুট এবং আউটপুট সম্পর্কে কিছু মন্তব্য সহ আমার ফাংশনগুলি এগিয়ে রাখি এবং কখনও কখনও আমি একটি উদাহরণ রাখি, আপনি এখানে দেখতে পারেন:

/*---------------------------*/
/*! interpolates between values
* @param[in] X_axis : contains X-values
* @param[in] Y_axis : contains Y-values
* @param[in] value  : X-value, input to the interpolation process
* @return[out]      : the interpolated value
* @example          : interpolate([2,0],[3,2],2.4) -> 0.8
*/
int interpolate(std::vector<int>& X_axis, std::vector<int>& Y_axis, int value)

স্পষ্টতই আপনার মন্তব্যের জন্য ব্যবহারের জন্য ফর্ম্যাটিংটি আপনার বিকাশের পরিবেশের উপর নির্ভর করে (ভিজ্যুয়াল স্টুডিও, একলিপের অধীনে জাভাডক, ...)

যতক্ষণ না এসসিই সম্পর্কিত, আমি ধরে নিচ্ছি আপনি এর দ্বারা নীচের অর্থ বোঝাতে চাইছেন:

bool b1;
b1 = somecomplicated_function(); // let me explain what this function does
bool b2 = false;
if (!b1) {                       // SCE : if first function call is already true,
                                 // no need to spend resources executing second function.
  b2 = someother_function();     // this function does something else
}

if (b1 || b2) {
...
}

-7

আপনি যদি কোনও সংস্থায় কাজ করেন তবে পাঠযোগ্যতা প্রয়োজনীয় এবং আপনার কোড অন্য কেউ পড়বে। আপনি যদি নিজের জন্য কোনও প্রোগ্রাম লিখে থাকেন তবে আপনি যদি বোধগম্য কোডের জন্য কর্মক্ষমতা ত্যাগ করতে চান তবে এটি আপনার হাতে।


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