সি ++ এ অ্যারে বা এসটিডি :: ভেক্টর ব্যবহার করে, পারফরম্যান্সের ব্যবধানটি কী?


208

আমাদের সি ++ কোর্সে তারা নতুন প্রকল্পগুলিতে আর সি ++ অ্যারে ব্যবহার না করার পরামর্শ দেয়। আমি যতদূর জানি স্ট্রাউটগ্রুপ নিজে অ্যারে ব্যবহার না করার পরামর্শ দেয়। তবে কি পারফরম্যান্সের উল্লেখযোগ্য পার্থক্য রয়েছে?


2
আপনি কেন ভাবেন যে এখানে পারফরম্যান্সের ব্যবধান রয়েছে।
মার্টিন ইয়র্ক

99
কারণ সাধারণত ভাল কার্যকারিতা নিয়ে আসে খারাপ প্রতিক্রিয়া।
টিউনুজ

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

132
আমি আশা করি লোকেরা "অকাল অনুকূলতা!" যখনই কেউ অভিনয় সম্পর্কিত কোনও সাধারণ প্রশ্ন জিজ্ঞাসা করছেন! প্রশ্নের উত্তর দিন এবং কেবল প্রাকৃতিকভাবে অনুমান করবেন না যে মানুষ অকালে কিছু করছে।
d7samurai

4
@ d7samaurai: একমত, আমি এখনও কাউকে ব্যবহার করার চেষ্টা দেখতে পেলামint main(int argc, const std::vector<string>& argv)
মার্ক কে কোয়ান

উত্তর:


189

সি ++ অ্যারে দিয়ে new(যা ডায়নামিক অ্যারে ব্যবহার করে) এড়ানো উচিত। আপনাকে আকারটি ট্র্যাক রাখতে সমস্যা রয়েছে এবং আপনাকে সেগুলি ম্যানুয়ালি মুছে ফেলা এবং সমস্ত ধরণের গৃহপালনা করা দরকার।

স্ট্যাকের অ্যারেগুলি ব্যবহার করাও নিরুৎসাহিত করা হয়েছে কারণ আপনার পরিসর পরীক্ষা করা নেই এবং চারপাশে অ্যারে পাস করা তার আকার সম্পর্কে কোনও তথ্য হারাবে (অ্যারে থেকে পয়েন্টার রূপান্তর)। আপনার boost::arrayসেই ক্ষেত্রে ব্যবহার করা উচিত , যা একটি ছোট শ্রেণিতে একটি সি ++ অ্যারে sizeআবৃত করে এবং এটির পুনরাবৃত্তি করার জন্য একটি ফাংশন এবং পুনরাবৃত্তি সরবরাহ করে।

এখন স্ট্যান্ড :: ভেক্টর বনাম স্থানীয় সি ++ অ্যারে (ইন্টারনেট থেকে নেওয়া):

// Comparison of assembly code generated for basic indexing, dereferencing, 
// and increment operations on vectors and arrays/pointers.

// Assembly code was generated by gcc 4.1.0 invoked with  g++ -O3 -S  on a 
// x86_64-suse-linux machine.

#include <vector>

struct S
{
  int padding;

  std::vector<int> v;
  int * p;
  std::vector<int>::iterator i;
};

int pointer_index (S & s) { return s.p[3]; }
  // movq    32(%rdi), %rax
  // movl    12(%rax), %eax
  // ret

int vector_index (S & s) { return s.v[3]; }
  // movq    8(%rdi), %rax
  // movl    12(%rax), %eax
  // ret

// Conclusion: Indexing a vector is the same damn thing as indexing a pointer.

int pointer_deref (S & s) { return *s.p; }
  // movq    32(%rdi), %rax
  // movl    (%rax), %eax
  // ret

int iterator_deref (S & s) { return *s.i; }
  // movq    40(%rdi), %rax
  // movl    (%rax), %eax
  // ret

// Conclusion: Dereferencing a vector iterator is the same damn thing 
// as dereferencing a pointer.

void pointer_increment (S & s) { ++s.p; }
  // addq    $4, 32(%rdi)
  // ret

void iterator_increment (S & s) { ++s.i; }
  // addq    $4, 40(%rdi)
  // ret

// Conclusion: Incrementing a vector iterator is the same damn thing as 
// incrementing a pointer.

নোট: আপনার সাথে অ্যারে বরাদ্দ তাহলে newও অ-বর্গ বস্তু (প্লেইন মত বরাদ্দ intএকটি ব্যবহারকারী সংজ্ঞায়িত কন্সট্রাকটর ছাড়া) অথবা ক্লাস এবং আপনি আপনার উপাদানের প্রাথমিকভাবে সক্রিয়া ব্যবহার আছে চাই না new-allocated অ্যারে কারণ কর্মক্ষমতা সুবিধার থাকতে পারে std::vectorসূচনা সব উপাদান ডিফল্ট মান (উদাহরণস্বরূপ, উদাহরণস্বরূপ) নির্মাণে (আমাকে স্মরণ করিয়ে দেওয়ার জন্য @ বার্নির ক্রেডিট)।


77
অভিশাপ এটিএন্ডটি সিনট্যাক্স আবিষ্কার করেছেন কে? কেবল যদি আমি জানতাম ... :)
মেহরদাদ আফশারি

4
এটি ভিজ্যুয়াল সি ++ সংকলকটির ক্ষেত্রে সত্য নয়। তবে জিসিসির পক্ষে এটি।
পুরো

5
আমার উত্তর পয়েন্ট যে ভেক্টর না আছে পয়েন্টার অপারেশন correponding তুলনায় ধীর হবে। অবশ্যই, এটা করতে পারেন (সহজ ডিবাগ মোড, অত্যধিক সক্ষম সক্ষম করে অর্জন করা) :) হতে
litb - জোহানেস Schaub

18
"ভেক্টরকে সূচীকরণের জন্য +1 পয়েন্টারকে সূচক করার মতো একই জঘন্য জিনিস" " এবং অন্যান্য সিদ্ধান্তের জন্য।
নওয়াজ

3
@ পাইওট্র৯৯৯ আমি আপনার সাথে তর্ক করতে যাচ্ছি না, তবে আপনি যখন উচ্চ স্তরের ভাষা শেখার পরে সমাবেশ শিখেন তখন ইন্টেল সিনট্যাক্স কিছু পিছনের দিকের, উপসর্গযুক্ত (সংখ্যা), প্রত্যয়যুক্ত (নির্দেশাবলী) এবং অস্পষ্ট (স্মৃতিতে অ্যাক্সেস করার চেয়ে) আরও অনেক কিছু বোঝায় ) এটিএন্ডটি সিনট্যাক্সের প্রকৃতি।
কোল জনসন

73

মাইক্রো অপ্টিমাইজার লোকের জন্য উপস্থাপক

মনে রাখবেন:

"প্রোগ্রামাররা তাদের প্রোগ্রামের অদ্বিতীয় অংশগুলির গতি সম্পর্কে চিন্তাভাবনা করে, বা উদ্বিগ্ন হয়, এবং ডিবাগিং এবং রক্ষণাবেক্ষণ বিবেচনা করার সময় দক্ষতার এই প্রচেষ্টাগুলি আসলে একটি শক্ত নেতিবাচক প্রভাব ফেলে। আমাদের ছোট কার্যকারিতা সম্পর্কে ভুলে যাওয়া উচিত, সম্পর্কে বলুন Of৯% সময়: অকালীন অপটিমাইজেশন হ'ল সমস্ত অশুভের মূল Yet

( সম্পূর্ণ উদ্ধৃতির জন্য রূপান্তরকে ধন্যবাদ )

ভেক্টরের পরিবর্তে (বা যাই হোক না কেন) কোনও সি অ্যারে ব্যবহার করবেন না কারণ আপনি বিশ্বাস করেন যে এটি নিম্ন স্তরের বলে মনে করা হওয়ায় এটি দ্রুততর। আপনি ভুল হবে।

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

এটি বলেছে, আমরা মূল প্রশ্নে ফিরে যেতে পারি।

স্ট্যাটিক / ডায়নামিক অ্যারে?

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

সব মিলিয়ে এটি দুটি বিভাগে পড়ে:

গতিশীল অ্যারে

ম্যালোক-এডি / নতুন-এড অ্যারেতে পয়েন্টার ব্যবহার করা স্ট্যান্ড :: ভেক্টর সংস্করণ হিসাবে সবচেয়ে দ্রুত এবং অনেক কম নিরাপদ হবে ( লিটব পোস্টটি দেখুন )।

সুতরাং একটি std :: ভেক্টর ব্যবহার করুন।

স্ট্যাটিক অ্যারে

স্ট্যাটিক অ্যারে ব্যবহার করা সর্বোত্তম:

  • std :: অ্যারে সংস্করণ হিসাবে দ্রুত
  • এবং অনেক কম নিরাপদ।

সুতরাং একটি স্টাডি :: অ্যারে ব্যবহার করুন ।

একীকরণবিহীন স্মৃতি

কখনও কখনও, একটি ব্যবহার vectorপরিবর্তে একটি কাঁচা বাফার একটি দৃশ্যমান খরচ incurs কারণ vectorমন্তব্য যেমন নির্মাণ এ বাফার আরম্ভ হবে, যখন কোড তা পরিবর্ত না, Bernie তার দ্বারা উত্তর

যদি এটি হয় তবে আপনি এটির unique_ptrপরিবর্তে একটি ব্যবহার করে এটি পরিচালনা করতে পারেন vectorবা যদি আপনার কোডলাইনে কেস ব্যতিক্রমী না হয় তবে প্রকৃতপক্ষে এমন একটি শ্রেণি লিখুন buffer_ownerযা সেই স্মৃতিটির মালিক হবে, এবং আপনাকে এতে সহজ এবং নিরাপদ অ্যাক্সেস দেবে, সহ এটির আকার পরিবর্তন করার মতো বোনাস (ব্যবহার করছেন realloc?) অথবা আপনার যা প্রয়োজন।


1
স্ট্যাটিক অ্যারেগুলিকেও সম্বোধন করার জন্য ধন্যবাদ - স্টাড :: ভেক্টর যদি কর্মক্ষমতার কারণে গতিশীলভাবে মেমরি বরাদ্দ না দেয় তবে অদৃশ্য।
টম

10
আপনি যখন বলছেন "একটি স্ট্যাটিক অ্যারে ব্যবহার করা উন্নত :: অ্যারে সংস্করণ হিসাবে তত দ্রুত হবে" এটি দেখায় যে আপনি কতটা পক্ষপাতদুষ্ট। এটি অন্য চারপাশে হওয়া উচিত, বুস্ট: অ্যারে স্থির অ্যারের মতো সেরা দ্রুততর হতে পারে।
টোটো

3
@ টোটো: এটি একটি ভুল বোঝাবুঝি: "স্ট্যাটিক অ্যারে ব্যবহার করা সর্বোত্তম ((বুস্ট :: অ্যারে সংস্করণ হিসাবে তত দ্রুত)) এবং& (আরও অনেক কম নিরাপদ)) হিসাবে এটি পড়তে হবে"। এটি স্পষ্ট করার জন্য আমি পোস্টটি সম্পাদনা করব। যাইহোক, সন্দেহের সুবিধার জন্য আপনাকে ধন্যবাদ।
প্যারাসেবল

1
স্টাডি :: অ্যারে সম্পর্কে কি?
পলম

4
সর্বদা সম্পূর্ণ উক্তিটি প্রদর্শন করুন। "প্রোগ্রামাররা তাদের প্রোগ্রামের অদ্বিতীয় অংশগুলির গতি সম্পর্কে চিন্তাভাবনা করে, বা উদ্বিগ্ন হয়, এবং ডিবাগিং এবং রক্ষণাবেক্ষণ বিবেচনা করার সময় দক্ষতার এই প্রচেষ্টাগুলি আসলে একটি শক্ত নেতিবাচক প্রভাব ফেলে। আমাদের ছোট কার্যকারিতা সম্পর্কে ভুলে যাওয়া উচিত, সম্পর্কে বলুন সময়ের ৯%%: অকালীন অপটিমাইজেশন হ'ল সমস্ত অশুভের মূল Yet তবুও আমাদের এই সমালোচনামূলক 3% তে আমাদের সুযোগগুলি অতিক্রম করা উচিত নয় "" অন্যথায় এটি অর্থহীন শব্দে পরিণত হয়।
রূপান্তর

32

ভেক্টরগুলি হুডের নীচে অ্যারে হয়। পারফরম্যান্স একই।

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

ভেক্টর পূরণ করার সাথে সাথে এটি নিজেই আকার পরিবর্তন করবে এবং এটি বোঝাতে পারে একটি নতুন অ্যারে বরাদ্দ, তারপরে এন কপি নির্মাণকারী এবং তারপরে প্রায় এন ডিস্ট্রাক্টর কল এবং তারপরে অ্যারে মুছবে delete

যদি আপনার কনস্ট্রাক্ট / ডেস্ট্রাক্ট ব্যয়বহুল হয় তবে ভেক্টরটি শুরু করার জন্য সঠিক আকার তৈরি করা থেকে আপনি আরও ভাল।

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


4
দুল: পারফরম্যান্সে একই বড় ও। স্টাড :: ভেক্টর কিছুটা বুককিপিং করে, সম্ভবত সম্ভবত অল্প পরিমাণে ব্যয় হয়। ওওহ, আপনার নিজের গতিশীল অ্যারেগুলি ঘূর্ণায়িত করার সময় আপনি একই বুককিপিংয়ের অনেক কাজ শেষ করেন।
ডিএমকেকে --- প্রাক্তন-মডারেটর বিড়ালছানা

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

জিসিসির এসটিডি :: ভেক্টর প্রকৃতপক্ষে একের পর এক ক্ষমতা বাড়িয়ে তোলে যদি আপনি পুশ_ব্যাক কল করেন।
bjhend

3
@bjhend তারপরে জিসিসির std::vectorশব্দগুলি মান-মেনে চলে না? আমি বিশ্বাস করি যে স্ট্যান্ডার্ডটির জন্য প্রয়োজনীয় vector::push_backধ্রুবক জটিলতা push_backথাকতে হবে এবং আপনি পুনর্বিবেচনার জন্য অ্যাকাউন্ট নেওয়ার পরে প্রতিটিের 1 টির দ্বারা ক্ষমতা বাড়ানো n ^ 2 জটিলতা হতে চলেছে। - অনুমান করা যায় যে কোনও ধরণের ক্ষতিকারক ক্ষমতা বৃদ্ধি পেয়েছে push_backএবং insert, ব্যর্থতার reserveফলে ভেক্টর সামগ্রীগুলির অনুলিপিগুলিতে সর্বাধিক ধ্রুবক ফ্যাক্টর বৃদ্ধি ঘটে। 1.5 সূচকীয় ভেক্টর বৃদ্ধি ফ্যাক্টর মানে হবে ~ অনেক প্রতিলিপি হিসাবে 3x যদি আপনি করতে ব্যর্থ reserve()
ইয়াক্ক - অ্যাডাম নেভ্রামোন্ট

3
@bjhend আপনি ভুল মানটি তাত্পর্যপূর্ণ বৃদ্ধি নিষিদ্ধ করে: .2 23.2.3 অনুচ্ছেদ 16 বলছে "টেবিল 101 101 এমন ক্রিয়াকলাপগুলি তালিকাভুক্ত করে যা কিছু ধরণের সিকোয়েন্স পাত্রে সরবরাহ করা হয় তবে অন্য নয় An এগুলি বাস্তবায়িত করবে যাতে ধারাবাহিকভাবে ধারাবাহিকভাবে সময় নিতে পারে "" (টেবিল 101 এর মধ্যে পুশব্যাক সহ একটি রয়েছে)। এখন দয়া করে এফইউডি ছড়িয়ে দেওয়া বন্ধ করুন। মূলধারার কোনও বাস্তবায়ন এই প্রয়োজনীয়তা লঙ্ঘন করে না। মাইক্রোসফ্টের স্ট্যান্ডার্ড সি ++ লাইব্রেরি 1.5x ফ্যাক্টর সহ বৃদ্ধি পায় এবং জিসিসি 2x ফ্যাক্টরের সাথে বৃদ্ধি পায়।
আর মার্টিনহো ফার্নান্দেস

27

কোনও কিছুর জবাব দিতে মেহেরদাদ বলেছিলেন:

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

মোটেও সত্য নয়। ভেক্টরগুলি অ্যারে / পয়েন্টারে খুব সুন্দরভাবে হ্রাস করে:

vector<double> vector;
vector.push_back(42);

double *array = &(*vector.begin());

// pass the array to whatever low-level code you have

এটি সমস্ত বড় এসটিএল বাস্তবায়নের জন্য কাজ করে। পরবর্তী স্ট্যান্ডার্ডে, এটি কাজ করার প্রয়োজন হবে (যদিও এটি আজ ঠিক ঠিক কাজ করে)।


1
বর্তমান মানটি এ জাতীয় কোনও কথা বলে না। এটি নিহিত, এবং এটি ধারাবাহিক স্টোরেজ হিসাবে প্রয়োগ করা হয়। তবে মানকটি কেবল বলেছে যে এটি একটি এলোমেলো অ্যাক্সেস ধারক (পুনরাবৃত্তকারী ব্যবহার করে)। পরবর্তী মানটি স্পষ্ট হবে।
ফ্রাঙ্ক ক্রুয়েজার

1
& * v.begin () কেবলমাত্র পুনরাবৃত্তিকে ডি-রেফারেন্সের ফলাফলের জন্য & অপারেটরকে প্রয়োগ করে। ডি-রেফারেন্সিং যে কোনও প্রকার ফিরে আসতে পারে। ঠিকানা-অপারেটরটি ব্যবহার করে আবার কোনও প্রকার ফিরে আসতে পারে। স্ট্যান্ডার্ডটি এটিকে মেমরির সংলগ্ন অঞ্চলে পয়েন্টার হিসাবে সংজ্ঞায়িত করে না।
ফ্রাঙ্ক ক্রুয়েজার

15
স্ট্যান্ডার্ডের আসল 1998 পাঠ্যের এটির প্রয়োজন ছিল না, তবে 2003 সালে একটি অ্যাডেন্ডাম ছিল যা এটি সম্বোধন করে, তাই এটি সত্যই স্ট্যান্ডার্ড দ্বারা আচ্ছাদিত। herbsutter.wordpress.com/2008/04/07/…
নেমানজা ত্রিফুনোভিচ

2
সি ++ 03 স্পষ্টতই বলেছে যে &v[n] == &v[0] + nবৈধ যেটি দেওয়া nহয় তা আকারের সীমার মধ্যে। এই বিবৃতি সম্বলিত অনুচ্ছেদটি C ++ 11 দিয়ে পরিবর্তন হয়নি।
bjhend

2
কেন শুধু এসটিডি :: ভেক্টর :: ডেটা ব্যবহার করবেন না?
পলম

15

আপনার C ++ 11 এ সরল অ্যারেগুলি ব্যবহার করার আরও কম কারণ রয়েছে।

প্রকৃতিতে দ্রুত থেকে ধীর থেকে ধীরে ধীরে তিন ধরণের অ্যারে রয়েছে তাদের বৈশিষ্ট্যগুলির উপর নির্ভর করে (অবশ্যই বাস্তবায়নের গুণাগুণ তালিকায় 3 কেসের ক্ষেত্রেও জিনিসগুলিকে সত্যই দ্রুততর করে তুলতে পারে):

  1. সংকলনের সময় আকারযুক্ত স্থিতিশীল। ---std::array<T, N>
  2. রানটাইমের সময় পরিচিত আকার সহ গতিশীল এবং কখনই আকার পরিবর্তন করা হয়নি। এখানে সাধারণ অপ্টিমাইজেশন হ'ল অ্যারেটি যদি সরাসরি স্ট্যাকের মধ্যে বরাদ্দ করা যায়। - উপলব্ধ নয়dynarrayসি ++ এর পরে সি ++ টিএস এ হতে পারে । সিতে ভিএলএ রয়েছে
  3. গতিশীল এবং রানটাইম এ পুনরায় আকার পরিবর্তনযোগ্য। ---std::vector<T>

টির জন্য নির্দিষ্ট সংখ্যক উপাদান সহ সাধারণ স্ট্যাটিক অ্যারে, std::array<T, N>সি ++ 11 ব্যবহার করুন ।

জন্য 2. নির্দিষ্ট আকার রানটাইম এ নিদিষ্ট অ্যারে, কিন্তু যে তাদের আকারের পরিবর্তন করবে না, সেখানে সি আলোচনা ++, 14 কিন্তু এটি একটি প্রযুক্তিগত স্পেসিফিকেশন সরানো এবং পরিশেষে C ++ 14 আউট করা হয়েছে।

জন্য 3. std::vector<T> সাধারণত গাদা মেমরি জন্য অনুরোধ জানানো হবে । এটির কার্য সম্পাদন ফলাফল হতে পারে, যদিও আপনি std::vector<T, MyAlloc<T>>কাস্টম বরাদ্দকারী দিয়ে পরিস্থিতির উন্নতি করতে ব্যবহার করতে পারেন । তুলনায় সুবিধা T mytype[] = new MyType[n];হ'ল আপনি এটির আকার পরিবর্তন করতে পারেন এবং এটি পয়েন্টারের কাছে ক্ষয় হবে না, যেমন সরল অ্যারেগুলি।

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


2
স্ট্যান্ড :: ডিনারএ। n3690 এ জাতীয় সংস্থার মন্তব্যগুলি পর্যালোচনা করার পরে, এই লাইব্রেরির উপাদানটি সি ++ 14 কার্যপত্রক থেকে আলাদা প্রযুক্তিগত বিবরণীতে ভোট দেওয়া হয়েছিল। এই ধারকটি N3797 হিসাবে সি ++ 14 খসড়াটির অংশ নয়। en.cppreferences.com/w/cpp/container/dynarray
মোহাম্মদ এল-নাকিব

1
খুব ভাল উত্তর। সংক্ষিপ্ত এবং সংক্ষিপ্ত বিবরণ, যে কোনও চেয়ে আরও বিশদ।
মোহাম্মদ এল-নাকিব

6

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


5

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


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

হ্যাঁ, তবে আপনি যদি ভেক্টরের অভ্যন্তরীণ জিনিসগুলি নিয়ে গণ্ডগোল করতে চান তবে ভেক্টর ব্যবহারের সুবিধা কম হবে। যাইহোক, মূল শব্দটি ছিল "সম্ভবত না"।
মেহরদাদ আফশারি

3
ভেক্টরগুলি কোথায় ব্যবহার করা যাবে না সে সম্পর্কে আমি কেবল জানি একটি ক্ষেত্রে: যদি আকারটি 0 হয় তবে & a [0] বা & * a.begin () কাজ করবে না। সি ++ ১ এক্স এডিটা () ফাংশন প্রবর্তনের মাধ্যমে এটি ঠিক করবে যা উপাদানগুলি রেখে অভ্যন্তরীণ বাফারটি ফেরত দেয়
জোহানেস স্কাউব - লিটব

আমার মনের নির্দিষ্ট দৃশ্যটি যখন আমি লিখেছিলাম সেটি স্ট্যাক-ভিত্তিক অ্যারে ছিল।
মেহরদাদ আফশারি

1
ইন্টারফেসিং ভেক্টর বা সি সহ যে কোনও স্বচ্ছ পাত্রে: vec.data()ডেটা এবং vec.size()আকারের জন্য। এটা এত সহজ।
জার্মেইন ডিয়াগো

5

দুলির অবদান সম্পর্কে

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


3

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

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


এটি উল্লেখ করা গুরুত্বপূর্ণ। প্রোফাইল ডিবাগ এসটিএল স্টাফ খুব খুব ধীর। এবং এটি এসটিএল মন্থর হওয়ার কারণগুলির একটি কারণ।
এরিক অ্যারোনস্টি

3

std::vectorযখন আপনি অবিচ্ছিন্ন বাফার চান (যেমন গন্তব্য হিসাবে গন্তব্য হিসাবে ব্যবহার করতে চান) একটি বনাম কাঁচা অ্যারে ব্যবহার করার ক্ষেত্রে অবশ্যই পারফরম্যান্সের প্রভাব রয়েছে memcpy()। একটি std::vectorডিফল্ট কনস্ট্রাক্টর ব্যবহার করে এর সমস্ত উপাদান সূচনা করবে। একটি কাঁচা অ্যারে না।

C ++ বৈশিষ্ট জন্য std:vectorকন্সট্রাকটর একটি গ্রহণ countযুক্তি (এটা তৃতীয় ফর্ম) পদ বলে:

Option বিকল্পভাবে ব্যবহারকারী সরবরাহকারী বরাদ্দ বরাদ্দ ব্যবহার করে বিভিন্ন ডেটা উত্স থেকে একটি নতুন ধারক তৈরি করে।

3) টি এর গণনা ডিফল্ট-সন্নিবেশিত উদাহরণ সহ ধারক তৈরি করে No কোনও অনুলিপি তৈরি করা হয় না।

জটিলতা

২-৩) গণনায় লিনিয়ার

একটি কাঁচা অ্যারে এই প্রারম্ভিককরণের ব্যয় বহন করে না।

আরও দেখুন কীভাবে আমি এসটিডি :: ভেক্টর <> এর সমস্ত উপাদানগুলিকে আরম্ভ করতে এড়াতে পারি?


2

উভয়ের মধ্যে পারফরম্যান্সের পার্থক্যটি খুব বেশি বাস্তবায়নের উপর নির্ভরশীল - আপনি যদি কোনও খারাপভাবে প্রয়োগ করা std :: ভেক্টরকে সর্বোত্তম অ্যারে বাস্তবায়নের সাথে তুলনা করেন তবে অ্যারেটি জিততে পারে তবে এটিকে ঘুরিয়ে দেয় এবং ভেক্টর জিততে পারে ...

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

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

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


1
আমি মনে করি যে কর্মক্ষমতা প্রয়োজনীয়তা পূরণ করতে (হে (1) লুক এবং সন্নিবেশ), আপনি প্রায় আছে এসটিডি :: ভেক্টর <> গতিশীল অ্যারে ব্যবহার করে বাস্তবায়ন করতে। অবশ্যই এটি করার সুস্পষ্ট উপায়।
dmckee --- প্রাক্তন-মডারেটর বিড়ালছানা

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

বর্ণিত হিসাবে একটি খারাপ ভেক্টর বাস্তবায়ন মানের সাথে সম্মতিযুক্ত হবে না। আপনি যদি ইন্ডিয়ারেশন চান std::dequeতবে ব্যবহার করা যেতে পারে।
ফিল 1970

1

আপনার যদি আকারকে গতিশীলভাবে সামঞ্জস্য করার প্রয়োজন না হয় তবে আপনার ক্ষমতা সংরক্ষণের মেমরির ওভারহেড রয়েছে (একটি পয়েন্টার / সাইজ_টি)। এটাই.


1

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

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


1

আমি যুক্তি দিয়েছি যে প্রাথমিক উদ্বেগ কর্মক্ষমতা নয়, তবে সুরক্ষা safety আপনি অ্যারে (উদাহরণস্বরূপ, আকার পরিবর্তন বিবেচনা করুন) দিয়ে প্রচুর ভুল করতে পারেন, যেখানে কোনও ভেক্টর আপনাকে প্রচুর ব্যথা বাঁচাতে পারে।


1

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


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

1

নিম্নলিখিত সহজ পরীক্ষা:

সি ++ অ্যারে বনাম ভেক্টর পারফরম্যান্স পরীক্ষার ব্যাখ্যা

"ভেক্টর এবং অ্যারে / পয়েন্টারগুলিতে বেসিক ইনডেক্সিং, ডেরেফারেন্সিং, এবং ইনক্রিমেন্ট অপারেশনের জন্য উত্পন্ন সমাবেশ কোডের তুলনা" থেকে প্রাপ্ত সিদ্ধান্তের বিরোধিতা করে।

অ্যারে এবং ভেক্টরগুলির মধ্যে অবশ্যই একটি পার্থক্য থাকতে হবে। পরীক্ষাটি তাই বলেছে ... কেবল এটি চেষ্টা করুন, কোডটি এখানে রয়েছে ...


1

কখনও কখনও অ্যারেগুলি ভেক্টরগুলির চেয়ে ভাল। আপনি যদি সর্বদা অবজেক্টের একটি নির্দিষ্ট দৈর্ঘ্যের সেটটি চালিত করেন তবে অ্যারেগুলি আরও ভাল। নিম্নলিখিত কোড স্নিপেটগুলি বিবেচনা করুন:

int main() {
int v[3];
v[0]=1; v[1]=2;v[2]=3;
int sum;
int starttime=time(NULL);
cout << starttime << endl;
for (int i=0;i<50000;i++)
for (int j=0;j<10000;j++) {
X x(v);
sum+=x.first();
}
int endtime=time(NULL);
cout << endtime << endl;
cout << endtime - starttime << endl;

}

যেখানে এক্স এর ভেক্টর সংস্করণ

class X {
vector<int> vec;
public:
X(const vector<int>& v) {vec = v;}
int first() { return vec[0];}
};

এবং এক্স এর অ্যারে সংস্করণটি হ'ল:

class X {
int f[3];

public:
X(int a[]) {f[0]=a[0]; f[1]=a[1];f[2]=a[2];}
int first() { return f[0];}
};

মূল () এর অ্যারে সংস্করণটি দ্রুত হবে কারণ আমরা অভ্যন্তরীণ লুপে প্রতিবার "নতুন" এর ওভারহেড এড়িয়ে চলেছি।

(এই কোডটি আমার দ্বারা comp.lang.c ++ পোস্ট করা হয়েছিল)।


1

আপনি যদি বহুমাত্রিক আচরণ উপস্থাপনের জন্য ভেক্টর ব্যবহার করছেন তবে একটি পারফরম্যান্স হিট হবে।

2 ডি + ভেক্টর কি পারফরম্যান্স হিটের কারণ?

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


0

একটি স্থির দৈর্ঘ্যের অ্যারে (যেমন int* v = new int[1000];বনাম std::vector<int> v(1000);, v1000-এ স্থির আকারের আকার সহ ) ধরে নেওয়া, একমাত্র পারফরম্যান্স বিবেচনা যা সত্যই গুরুত্বপূর্ণ (বা আমি যখন একই ধরণের সমস্যায় পড়েছিলাম তখন আমার কাছে কমপক্ষে বিষয়টি বিবেচনা করা হয়েছিল) একটিতে অ্যাক্সেসের গতি উপাদান। আমি এসটিএল এর ভেক্টর কোডটি সন্ধান করেছি এবং আমি যা পেয়েছি তা এখানে:

const_reference
operator[](size_type __n) const
{ return *(this->_M_impl._M_start + __n); }

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

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