X + = এক্স = এক্স + এ এর ​​চেয়ে দ্রুত?


84

আমি স্ট্রোস্ট্রপের "দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ" পড়ছিলাম, যেখানে তিনি বলেছেন যে কোনও ভেরিয়েবলের সাথে কিছু যুক্ত করার দুটি উপায়ের বাইরে says

x = x + a;

এবং

x += a;

তিনি পছন্দ করেন +=কারণ এটি সম্ভবত আরও কার্যকরভাবে প্রয়োগ করা হয়েছে। আমি মনে করি তার অর্থ এটি খুব দ্রুত কাজ করে।
তবে তা কি সত্যি? এটি যদি সংকলক এবং অন্যান্য বিষয়ের উপর নির্ভর করে তবে আমি কীভাবে চেক করব?


45
"দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ" প্রথম প্রকাশিত হয়েছিল 1985 সালে The
জোজি

4
দুটি লাইন সম্ভাব্যভাবে সম্পূর্ণ আলাদা কিছু করতে পারে। আপনি আরও নির্দিষ্ট হতে হবে।
কেরেক এসবি


26
আধুনিক প্রশ্নকারীরা এই প্রশ্নগুলিকে 'পুরানো' হিসাবে বিবেচনা করার জন্য যথেষ্ট স্মার্ট।
gd1

4
এটি পুনরায় খোলা হয়েছে কারণ সদৃশ প্রশ্নটি সি নয় সি ++ সম্পর্কে জিজ্ঞাসা করে।
কেভ

উত্তর:


212

কোন কম্পাইলার মূল্য তার লবণ ঠিক কোন বিল্ট-ইন টাইপ (উভয় নির্মান জন্য একই মেশিনে ভাষার ক্রম উত্পন্ন করবে int, floatইত্যাদি) যতদিন বিবৃতি সত্যিই হিসাবে সহজ হিসাবে হিসাবে x = x + a; এবং অপ্টিমাইজেশান সক্রিয় করা হয় । (উল্লেখযোগ্যভাবে, জিসিসি -O0, যা ডিফল্ট মোড, অ্যান্টি-অপ্টিমাইজেশানগুলি সম্পাদন করে যেমন মেমরিতে সম্পূর্ণ অপ্রয়োজনীয় স্টোরগুলি সন্নিবেশ করানো যাতে ডিবাগাররা সর্বদা পরিবর্তনশীল মানগুলি খুঁজে পেতে পারে তা নিশ্চিত করার জন্য))

বিবৃতি যদি আরও জটিল হয় তবে এগুলি ভিন্ন হতে পারে। মনে করুন fএকটি ফাংশন যা একটি পয়েন্টার দেয়, তারপরে

*f() += a;

fশুধুমাত্র একবার কল , যদিও

*f() = *f() + a;

দু'বার ডাকছে। যদি fপার্শ্ব প্রতিক্রিয়া আছে, দুই এক (সম্ভবত আধুনিক) ভুল হবে। এমনকি যদি fপার্শ্ব প্রতিক্রিয়া নেই, কম্পাইলার, দ্বিতীয় কল নিষ্কাশন করতে সক্ষম নাও হতে পারে, তাই আধুনিক প্রকৃতপক্ষে মন্থর হতে পারে।

এবং যেহেতু আমরা এখানে সি ++ এর কথা বলছি, শ্রেণি ধরণের ক্ষেত্রে ওভারলোড operator+ও করা পরিস্থিতি সম্পূর্ণ আলাদা operator+=। যদি xএ জাতীয় ধরণ থাকে, তবে - অপ্টিমাইজেশনের আগে - x += aঅনুবাদ করে

x.operator+=(a);

যেখানে x = x + aঅনুবাদ

auto TEMP(x.operator+(a));
x.operator=(TEMP);

এখন, ক্লাসটি সঠিকভাবে লেখা থাকলে এবং সংকলকের অপ্টিমাইজারটি যথেষ্ট ভাল, উভয়ই একই মেশিনের ভাষা উত্পন্ন করবে, তবে এটি কোনও অন্তর্নির্মিত প্রকারের মতো নিশ্চিত জিনিস নয়। স্ট্রস্ট্রপ যখন ব্যবহারের জন্য উত্সাহিত করেন তখন সম্ভবত এটিই চিন্তাভাবনা করে +=


14
আরও একটি দিক রয়েছে - পাঠযোগ্যতা । সি ++ র প্রতিযোগিতা যুক্ত exprকরার varজন্য var+=exprএবং এটি অন্যভাবে লেখা পাঠকদের বিভ্রান্ত করবে।
টাদিউস কোপেক

21
আপনি যদি নিজেকে লেখার বিষয়টি খুঁজে পান তবে আপনি *f() = *f() + a;কী অর্জন করতে চাইছেন সে সম্পর্কে আপনি খুব
অ্যাডাম ডেভিস

4
এবং যদি var = var + এক্সপ্রেস আপনাকে বিভ্রান্ত করে, তবে বর্ণ + = এক্সপ্রেস না করে তবে আপনি যে বিজোড় সফটওয়্যার প্রকৌশলীর সাথে আমার দেখা হয়ে গেছে। হয় পাঠযোগ্য; কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনি সামঞ্জস্য
রয়েছেন

7
@ পাইওটারডব্রোগোস্ট: প্রশ্নের উত্তর দেওয়ার ক্ষেত্রে কী ভুল? যাই হোক না কেন, এটি প্রশ্নকর্তা হওয়া উচিত যারা অনুলিপিগুলির জন্য পরীক্ষা করেছিলেন।
গর্পিক

4
@ পাইওটারডব্রোগোস্ট আমার কাছে মনে হচ্ছে আপনি যেন একটু ... হিংসুক ... আপনি যদি নকল খুঁজতে সন্ধান করতে চান তবে তার জন্য যান। আমি একজনের পক্ষে দু'পাশের খোঁজ না করে প্রশ্নের জবাব দেওয়া পছন্দ করি (যদি না এটি একটি প্রশ্ন হয় যা আমি বিশেষত আগে দেখেছি বলে মনে করি)। এটি কখনও কখনও দ্রুততর হতে পারে এবং যে প্রশ্নটি দ্রুত জিজ্ঞাসা করেছিল তাকেই সহায়তা করতে পারে। এছাড়াও, নোট করুন যে এটি এমনকি লুপ নয়। 1একটি ধ্রুবক, aএকটি অস্থির হতে পারে, একটি ব্যবহারকারী সংজ্ঞায়িত প্রকার, বা যাই হোক না কেন। একদম ই অন্যরকম. আসলে কীভাবে এটি বন্ধ হয়ে গেল আমি বুঝতে পারি না।
লুচিয়ান গ্রিগোর

56

আপনি বিচ্ছিন্নতা দেখে পরীক্ষা করতে পারেন, যা একই হবে।

প্রাথমিক ধরণের জন্য , উভয়ই সমান দ্রুত।

এটি একটি ডিবাগ বিল্ড দ্বারা উত্পাদিত আউটপুট (যেমন কোনও অপ্টিমাইজেশন নেই):

    a += x;
010813BC  mov         eax,dword ptr [a]  
010813BF  add         eax,dword ptr [x]  
010813C2  mov         dword ptr [a],eax  
    a = a + x;
010813C5  mov         eax,dword ptr [a]  
010813C8  add         eax,dword ptr [x]  
010813CB  mov         dword ptr [a],eax  

ব্যবহারকারী-সংজ্ঞায়িত প্রকারের জন্য , যেখানে আপনি ওভারলোড করতে পারেন operator +এবং operator +=, এটি তাদের সম্পর্কিত বাস্তবায়নের উপর নির্ভর করে।


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

ব্যবহারকারী সংজ্ঞায়িত প্রকার সম্পর্কে কীভাবে? ভাল সংকলকগুলির সমতুল্য সমাবেশ তৈরি করা উচিত , তবে এরকম কোনও গ্যারান্টি নেই।
mfontanini

4
@ লুচিয়ানগ্রিগোর নপ, যদি a1 হয় এবং xহয় তবে সংকলকটি volatileউত্পন্ন করতে পারে inc DWORD PTR [x]। এটি ধীর।
জেমস

4
@ শিফা সংকলক-নির্ভর নয়, তবে বিকাশকারী-নির্ভর। আপনি operator +কিছুই operator +=করতে এবং 100000 তম সংখ্যাটি গণনা এবং তারপরে বাস্তবায়ন করতে পারেন। অবশ্যই, এটি করতে বোবা জিনিস হবে, তবে এটি সম্ভব।
লুচিয়ান গ্রিগোর

4
@James যদি আপনার প্রোগ্রাম মধ্যে কর্মক্ষমতা পার্থক্য থেকে বুদ্ধিমানের ++xএবং temp = x + 1; x = temp;খুব সম্ভবত এটা সমাবেশ বরং গ চেয়ে লিখতে হবে ++ তারপর ...
EmirCalabuch

11

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


8

এটি সত্যই x এবং a এর ধরণ এবং + এর প্রয়োগের উপর নির্ভর করে। জন্য

   T x, a;
   ....
   x = x + a;

সংকলকটি এক্স + এর মান ধারণ করতে একটি অস্থায়ী টি তৈরি করতে হবে যখন এটি এর মূল্যায়ন করে, যা এটি পরে এক্সকে নির্ধারিত করতে পারে। (এই অপারেশনের সময় এটি এক্স বা একটি কর্মক্ষেত্র হিসাবে ব্যবহার করতে পারে না)।

এক্স + = এ এর ​​জন্য অস্থায়ী প্রয়োজন হয় না।

তুচ্ছ প্রকারের জন্য, কোনও পার্থক্য নেই।


8

মেশিনকে যে পরিমাণ কাজ করতে হবে তার মধ্যে x = x + aএবং x += aতার মধ্যে পার্থক্য রয়েছে - কিছু সংকলক এটি অপ্টিমাইজ করতে পারে (এবং সাধারণত করতে পারে) তবে সাধারণত, আমরা যদি কিছুক্ষণের জন্য অপ্টিমাইজেশন উপেক্ষা করি তবে কী হয় পূর্ব কোড স্নিপেটে, মেশিনটির জন্য xদু'বারের জন্য মূল্য অনুসন্ধান করতে হবে , তবে একের পরে এই চেহারাটি কেবল একবারই হওয়া দরকার।

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

পিএস: স্ট্যাক ওভারফ্লোতে প্রথম উত্তর!


6

আপনি এই সি ++ লেবেল হিসাবে আপনার পোস্ট করা দুটি বিবৃতি থেকে জানা উপায় নেই। আপনাকে 'x' কী তা জানতে হবে (এটি উত্তর '42' এর মতো কিছুটা)। যদি xকোনও পিওড হয় তবে এটি আসলে খুব বেশি পার্থক্য আনবে না। তবে, যদি xকোনও শ্রেণি হয়, তবে পদ্ধতি operator +এবং operator +=পদ্ধতিগুলির জন্য ওভারলোডগুলি থাকতে পারে যার মধ্যে বিভিন্ন আচরণ থাকতে পারে যা মৃত্যুদণ্ড কার্যকর করার সময়কে আলাদা আলাদা করে তোলে।


6

আপনি যদি বলেন যে +=আপনি সংকলকটির জন্য জীবনকে অনেক সহজ করে তুলছেন। সংকলকটি x = x+aযেটি একইরূপে তা সনাক্ত করার জন্য, সংকলকটি করতে x += aহবে

  • xএটির কোনও পার্শ্ব প্রতিক্রিয়া নেই এবং তা সর্বদা একই এল-মানকে বোঝায় তা নিশ্চিত করতে বাম দিকে ( ) বিশ্লেষণ করুন । উদাহরণস্বরূপ, এটি হতে পারে z[i], এবং এটি নিশ্চিত যে উভয় করতে হয়েছে zএবং iপরিবর্তন করবেন না।

  • ডান হাতের দিকটি বিশ্লেষণ করুন x+aএবং নিশ্চিত করুন যে এটি একটি সংশ্লেষ, এবং বাম হাতটি একবারে এবং কেবল একবার ডান হাতের দিকে ঘটে, যদিও এটি রূপান্তরিত হতে পারে, যদিও এটি z[i] = a + *(z+2*0+i)

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


5

একটি কংক্রিট উদাহরণের জন্য, একটি সাধারণ জটিল সংখ্যা প্রকারের কল্পনা করুন:

struct complex {
    double x, y;
    complex(double _x, double _y) : x(_x), y(_y) { }
    complex& operator +=(const complex& b) {
        x += b.x;
        y += b.y;
        return *this;
    }
    complex operator +(const complex& b) {
        complex result(x+b.x, y+b.y);
        return result;
    }
    /* trivial assignment operator */
}

A = a + b কেসের জন্য এটি একটি অতিরিক্ত অস্থায়ী পরিবর্তনশীল করতে হবে এবং তারপরে এটি অনুলিপি করতে হবে।


এটি খুব সুন্দর উদাহরণ, 2 অপারেটর কীভাবে প্রয়োগ করেছে তা দেখায়।
গ্রিজেশ চৌহান

5

আপনি ভুল প্রশ্ন জিজ্ঞাসা করছেন।

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

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

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


মঞ্জুরি দেওয়া হয়েছে, তবে এটি একটি নিম্ন স্তরের প্রশ্ন হিসাবে বোঝানো হয়েছিল, বড় চিত্র নয় "কখন এই ধরণের পার্থক্যটি বিবেচনা করা উচিত" একটি।
শিফা

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

4

আমি মনে করি এটি মেশিন এবং তার স্থাপত্যের উপর নির্ভর করবে। যদি এর স্থাপত্যটি অপ্রত্যক্ষ মেমরিকে সম্বোধন করার অনুমতি দেয় তবে সংকলক লেখক কেবল এই কোডটি ব্যবহার করুন (অপ্টিমাইজেশনের জন্য):

mov $[y],$ACC

iadd $ACC, $[i] ; i += y. WHICH MIGHT ALSO STORE IT INTO "i"

তবে, i = i + yঅনুবাদ করা যেতে পারে (অপ্টিমাইজেশন ছাড়াই):

mov $[i],$ACC

mov $[y],$B 

iadd $ACC,$B

mov $B,[i]


এটি বলেছিল যে, অন্যান্য জটিলতা যেমন iফাংশন রিটার্ন পয়েন্টার ইত্যাদি also জিসিসি সহ বেশিরভাগ উত্পাদন স্তরের সংকলক উভয় স্টেটমেন্টের জন্য একই কোড তৈরি করে (যদি তারা পূর্ণসংখ্যা হয়)।


2

না, উভয় উপায়ে একই হ্যান্ডেল করা হয়।


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