আমি ৫ টি সাধারণ বিভাগ সম্পর্কে সচেতন যেখানে সি ++ ১১ হিসাবে একটি সি ++ ০৩ সংকলক পুনরায় সংযোগ করা আনবাউন্ড পারফরম্যান্স বৃদ্ধির কারণ হতে পারে যা কার্যত বাস্তবায়নের মানের সাথে সম্পর্কিত নয়। এগুলি চলন্ত শব্দার্থবিজ্ঞানের সমস্ত প্রকরণ।
std::vector বরাদ্দ
struct bar{
std::vector<int> data;
};
std::vector<bar> foo(1);
foo.back().data.push_back(3);
foo.reserve(10); // two allocations and a delete occur in C++03
প্রত্যেক সময় fooএর বাফার C ++ 03 পুনরায় বরাদ্দ করা হয় তা প্রত্যেক কপি vectorমধ্যে bar।
সি ++ 11 এ এটি পরিবর্তিতভাবে এসগুলি সরিয়ে দেয় bar::dataযা মূলত বিনামূল্যে।
এই ক্ষেত্রে, এই ভিতরে অপ্টিমাইজেশন উপর নির্ভর stdধারক vector। নীচের প্রতিটি ক্ষেত্রে, stdপাত্রে ব্যবহার কেবলমাত্র কারণ moveআপনি যখন আপনার সংকলক আপগ্রেড করেন তখন সি ++ 11 "স্বয়ংক্রিয়ভাবে" তে দক্ষ শব্দার্থক থাকে সেগুলি সি ++ অবজেক্ট । যে সামগ্রীগুলি এটি একটি stdপাত্রে অন্তর্ভুক্ত করে তা অবরুদ্ধ করে না সেগুলি স্বয়ংক্রিয়ভাবে উন্নত moveকনস্ট্রাক্টরের উত্তরাধিকারী ।
এনআরভিও ব্যর্থতা
যখন এনআরভিও (নামযুক্ত রিটার্ন মান অপ্টিমাইজেশন) ব্যর্থ হয়, সি ++ 03 এ এটি অনুলিপি পিছনে পড়ে যায়, সি ++ 11 এ এটি চলাচলে ফিরে যায়। এনআরভিওর ব্যর্থতা সহজ:
std::vector<int> foo(int count){
std::vector<int> v; // oops
if (count<=0) return std::vector<int>();
v.reserve(count);
for(int i=0;i<count;++i)
v.push_back(i);
return v;
}
অথবা এমনকি:
std::vector<int> foo(bool which) {
std::vector<int> a, b;
// do work, filling a and b, using the other for calculations
if (which)
return a;
else
return b;
}
আমাদের তিনটি মান রয়েছে - ফাংশনের মধ্যে ফেরতের মান এবং দুটি পৃথক মান। এলিশন ফাংশনটির মধ্যে থাকা মানগুলিকে রিটার্ন মানটির সাথে 'একত্রিত' করতে দেয় তবে একে অপরের সাথে নয়। একে অপরের সাথে একত্রিত না হয়ে তারা উভয়ই রিটার্ন মানের সাথে একত্রী হতে পারে না।
মূল সমস্যাটি হ'ল এনআরভিও এলিজেনটি ভঙ্গুর এবং returnসাইটের কাছাকাছি না হওয়া পরিবর্তনের কোডটি হঠাৎ করে কোনও ডায়াগনস্টিক নির্গমন ছাড়াই সেই জায়গাটিতে ব্যাপক পারফরম্যান্স হ্রাস পেতে পারে। বেশিরভাগ এনআরভিও ব্যর্থতার ক্ষেত্রে সি ++ 11 এর সাথে শেষ হয় move, আর সি ++ 03 একটি অনুলিপি সহ শেষ হয়।
একটি ফাংশন যুক্তি ফিরে
এলিজেন এখানেও অসম্ভব:
std::set<int> func(std::set<int> in){
return in;
}
সি ++ 11 এ এটি সস্তা: সি ++ 03 এ অনুলিপিটি এড়ানোর কোনও উপায় নেই। ফাংশনগুলিতে যুক্তিগুলি রিটার্ন মানের সাথে আলাদা করা যায় না, কারণ প্যারামিটারের জীবনকাল এবং অবস্থান এবং রিটার্ন মান কলিং কোড দ্বারা পরিচালিত হয়।
তবে সি ++ 11 এক থেকে অন্যটিতে যেতে পারে। (একটি খেলনা উদাহরণে, কিছু কিছু করা হতে পারে set)।
push_back অথবা insert
অবশেষে ধারকগুলিতে এলিজেনটি ঘটে না: তবে সি ++ 11 ওভারলোডগুলি চালকগুলি সন্নিবেশ করান, যা অনুলিপিগুলি সংরক্ষণ করে।
struct whatever {
std::string data;
int count;
whatever( std::string d, int c ):data(d), count(c) {}
};
std::vector<whatever> v;
v.push_back( whatever("some long string goes here", 3) );
সি ++ 03 এ একটি অস্থায়ী whateverতৈরি হয়, তারপরে এটি ভেক্টরে অনুলিপি করা হয় v। 2 টি std::stringবাফার বরাদ্দ করা হয়েছে, প্রতিটি অভিন্ন ডেটা সহ এবং একটি ত্যাগ করা হয়।
সি ++ 11 এ একটি অস্থায়ী whateverতৈরি করা হয়। এর পরে whatever&& push_backওভারলোড moveভেক্টরটিতে সেই অস্থায়ী v। একটি std::stringবাফার বরাদ্দ করা হয়েছে, এবং ভেক্টরে সরানো হয়েছে। একটি খালি std::stringফেলে দেওয়া হয়।
নিয়োগ
নীচে @ জারোড 42 এর উত্তর থেকে চুরি হয়েছে।
এলিজেনশন অ্যাসাইনমেন্টের সাথে ঘটতে পারে না, তবে স্থানান্তর থেকে পারে।
std::set<int> some_function();
std::set<int> some_value;
// code
some_value = some_function();
এখানে some_functionথেকে একজন প্রার্থীকে এলিডে ফিরিয়ে দেয়, তবে এটি সরাসরি কোনও অবজেক্ট তৈরি করতে ব্যবহৃত না হওয়ায় এটি আলাদা করা যায় না। সি ++ তে, উপরের ফলাফলগুলিতে অস্থায়ী সামগ্রীতে অনুলিপি করা হচ্ছে some_value। সি ++ 11 এ এটি সরানো হয়েছে some_value, যা মূলত বিনামূল্যে।
উপরের পুরো প্রভাবের জন্য, আপনার কাছে এমন একটি সংকলক প্রয়োজন যা মুভ কনস্ট্রাক্টর এবং অ্যাসাইনমেন্টকে সংশ্লেষিত করে।
এমএসভিসি 2013 এর মধ্যে মুভ কনস্ট্রাক্টরগুলি প্রয়োগ করে std কনটেইনারগুলিতে করে, তবে আপনার ধরণের মুভ কনস্ট্রাক্টরগুলিকে সংশ্লেষিত করে না।
সুতরাং std::vectorএস এবং অনুরূপ সমন্বিত ধরণেরগুলি এমএসভিসি ২০১৩ তে এই ধরনের উন্নতি পায় না, তবে তাদের এমএসভিসি ২০১৫ এ পাওয়া শুরু করবে।
ঝনঝন এবং জিসিসি দীর্ঘকাল থেকেই অন্তর্নিহিত মুভ কনস্ট্রাক্টর প্রয়োগ করেছে। ইন্টেলের 2013 সংকলক আপনি পাস করলে -Qoption,cpp,--gen_move_operationsমুভি কনস্ট্রাক্টরের অন্তর্নিহিত প্রজন্মকে সমর্থন করবে (তারা এমএসভিসি ২০১৩ এর সাথে ক্রস-সামঞ্জস্যপূর্ণ হওয়ার প্রয়াসে ডিফল্টরূপে এটি করবেন না)।