সি ++ এ দক্ষ স্ট্রিং কনক্যান্টেশন


108

আমি শুনেছি কয়েকজন লোক স্ট্যান্ড :: স্ট্রিং ও "+" অপারেটর সম্পর্কে উদ্বেগ প্রকাশ করে কনটেনটেশনের গতি বাড়ানোর জন্য বিভিন্ন কর্মকাণ্ডে। এগুলির কি আসলেই প্রয়োজনীয়? যদি তা হয় তবে, সি ++ তে স্ট্রিং সংযুক্ত করার সর্বোত্তম উপায় কী?


13
মূলত + একটি সংঘবদ্ধতা অপারেটর নয় (যেমন এটি একটি নতুন স্ট্রিং উত্পন্ন করে)। সংক্ষেপণের জন্য + = ব্যবহার করুন।
মার্টিন ইয়র্ক

1
যেহেতু সি ++ ১১, একটি গুরুত্বপূর্ণ বিষয় রয়েছে: অপারেটর + তার অপারেটরগুলির মধ্যে একটিকে সংশোধন করতে পারে এবং যদি সেই অপারেন্ডকে যথাযথ রেফারেন্স দিয়ে পাস করা হয় তবে এটি বাই-পেজে ফিরে আসতে পারে। libstdc++ উদাহরণস্বরূপ এটি করে । সুতরাং, অস্থায়ী সংস্থাগুলি সহ অপারেটরকে + কল করার সময়, এটি প্রায়-ভাল-ভাল পারফরম্যান্স অর্জন করতে পারে - সম্ভবত পাঠ্যতার পক্ষে, এটির খেলাপি হয়ে যাওয়ার পক্ষে যুক্তি, যদি না কারও কাছে এটির কোনও বাধা না দেখায় bench তবে, একটি স্ট্যান্ডার্ডাইজড ভেরিয়েডিক append()অনুকূল এবং পাঠযোগ্য উভয়ই হতে পারে ...
আন্ডারস্কোর_আর

উত্তর:


85

অতিরিক্ত কাজটি সম্ভবত এটির পক্ষে উপযুক্ত নয়, যদি না আপনার সত্যিই দক্ষতার প্রয়োজন হয়। পরিবর্তে অপারেটর + = ব্যবহার করে আপনার সম্ভবত আরও ভাল দক্ষতা হবে।

এখন এই দাবি অস্বীকার করার পরে, আমি আপনার আসল প্রশ্নের উত্তর দেব ...

এসটিএল স্ট্রিং ক্লাসের দক্ষতা আপনি যে এসটিএল ব্যবহার করছেন তার উপর নির্ভর করে।

আপনি দক্ষতার গ্যারান্টি দিতে পারেন এবং সি বিল্ট-ইন ফাংশনগুলির মাধ্যমে ম্যানুয়ালি কনটেনটেশন করে নিজেকে আরও বেশি নিয়ন্ত্রণ করতে পারেন

অপারেটর + কেন দক্ষ নয়:

এই ইন্টারফেসটি একবার দেখুন:

template <class charT, class traits, class Alloc>
basic_string<charT, traits, Alloc>
operator+(const basic_string<charT, traits, Alloc>& s1,
          const basic_string<charT, traits, Alloc>& s2)

আপনি দেখতে পারবেন যে প্রতিটি + এর পরে একটি নতুন অবজেক্ট ফিরে আসে। তার অর্থ প্রতিবার একটি নতুন বাফার ব্যবহৃত হয়। আপনি যদি এক টন অতিরিক্ত + অপারেশন করছেন তবে এটি দক্ষ নয়।

আপনি কেন এটি আরও দক্ষ করতে পারেন:

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

বাস্তবায়নের জন্য বিবেচনাগুলি:

  • স্ট্রিংয়ের দৈর্ঘ্যের উপর নজর রাখুন।
  • স্ট্রিং এবং স্টার্টের শেষে একটি পয়েন্টার রাখুন, বা কেবল শুরু করুন এবং স্ট্রিংটির শেষ সন্ধানের জন্য অফসেট হিসাবে স্টার্ট + দৈর্ঘ্যটি ব্যবহার করুন।
  • নিশ্চিত হয়ে নিন যে আপনি যে স্টাফের স্ট্রিংটি স্ট্রিং করছেন সেখানে সেটি যথেষ্ট বড়, যাতে আপনাকে ডেটা পুনরায় বরাদ্দ করার প্রয়োজন হয় না
  • স্ট্রাইক্যাট এর পরিবর্তে স্ট্রিপিপি ব্যবহার করুন যাতে স্ট্রিংয়ের শেষ সন্ধানের জন্য আপনার স্ট্রিংয়ের দৈর্ঘ্যের উপর পুনরাবৃত্তি করতে হবে না।

দড়ি তথ্য কাঠামো:

আপনার যদি সত্যই দ্রুত কনটেনটেশনগুলির প্রয়োজন হয় তবে দড়ি ডেটা স্ট্রাকচার ব্যবহার করে বিবেচনা করুন ।


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

1
আমি বলব না যে এসটিএল এবং স্ট্রিং একসাথে ব্যবহার করা ভুল। স্যাজি.টেক
ব্রায়ান আর বন্ডি

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

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

4
আপনি কি দয়া করে স্পষ্ট করতে পারেন বা কেন আপনি নিজের বাফারগুলির জন্য স্ট্যাকটি স্তূপটি ব্যবহার করতে পারেন যা আরও কার্যকর। ? এই দক্ষতার পার্থক্যটি কোথা থেকে আসে?
h7r

76

আপনার চূড়ান্ত স্থানটি আগে সংরক্ষণ করুন, তারপরে একটি বাফার সহ অ্যাপেন্ড পদ্ধতিটি ব্যবহার করুন। উদাহরণস্বরূপ, বলুন যে আপনি আপনার চূড়ান্ত স্ট্রিংয়ের দৈর্ঘ্য 1 মিলিয়ন অক্ষর হতে হবে:

std::string s;
s.reserve(1000000);

while (whatever)
{
  s.append(buf,len);
}

17

আমি এটি সম্পর্কে চিন্তা করবেন না। যদি আপনি এটি কোনও লুপে করেন তবে স্ট্রিংগুলি সর্বদা পুনঃব্যবস্থাপনা হ্রাস করার জন্য মেমরিটিকে পূর্ব থেকে নিযুক্ত করবে - কেবলমাত্র operator+=সেই ক্ষেত্রে ব্যবহার করুন । এবং আপনি যদি এটি ম্যানুয়ালি করেন তবে এটির মতো বা আরও দীর্ঘ কিছু

a + " : " + c

তারপরে এটি অস্থায়ীতা তৈরি করছে - এমনকি সংকলক কিছু রিটার্ন মানের অনুলিপিগুলি সরিয়ে দিতে পারে। এটা এ কারণেও যে একটি ধারাবাহিকভাবে নামক operator+জানে না এটা কিনা রেফারেন্স প্যারামিটার রেফারেন্স একটি নামাঙ্কিত বস্তু বা একটি অস্থায়ী উপ থেকে প্রত্যাগত operator+আবাহন। আমি প্রথমে প্রোফাইল না দেওয়ার আগে এটির বিষয়ে চিন্তা করব না not তবে এটি দেখানোর জন্য একটি উদাহরণ নেওয়া যাক। বাঁধাই পরিষ্কার করার জন্য আমরা প্রথমে প্রথম বন্ধনীর পরিচয় করি। আমি স্পষ্টতার জন্য ব্যবহৃত ফাংশন ঘোষণার পরে যুক্তিগুলি সরাসরি রেখেছি। তার নীচে আমি ফলাফলটি প্রকাশের পরে কী তা দেখায়:

((a + " : ") + c) 
calls string operator+(string const&, char const*)(a, " : ")
  => (tmp1 + c)

এখন, এই সংযোজনটিতে, tmp1অপারেটরকে প্রথম কল দ্বারা প্রদর্শিত আর্গুমেন্টগুলি দিয়ে ফিরে আসে। আমরা ধরে নিই যে সংকলকটি সত্যই চতুর এবং রিটার্ন মানের অনুলিপিটিকে অনুকূলিত করে। সুতরাং আমরা এক নতুন স্ট্রিং, যাতে এর সংযুক্তকরণের রয়েছে দিয়ে শেষ aএবং " : "। এখন, এটি ঘটে:

(tmp1 + c)
calls string operator+(string const&, string const&)(tmp1, c)
  => tmp2 == <end result>

এটি নিম্নলিখিতের সাথে তুলনা করুন:

std::string f = "hello";
(f + c)
calls string operator+(string const&, string const&)(f, c)
  => tmp1 == <end result>

এটি অস্থায়ী এবং নামযুক্ত স্ট্রিংয়ের জন্য একই ফাংশনটি ব্যবহার করছে! তাই কম্পাইলার হয়েছে একটি নতুন স্ট্রিং এবং যে সংযোজন মধ্যে যুক্তি কপি করে শরীর থেকে ফিরে যাওয়ার operator+। এটি একটি অস্থায়ী স্মৃতি নিতে পারে না এবং এটিতে যুক্ত হতে পারে। এক্সপ্রেশনটি যত বড়, তত বেশি কপির কাজ করতে হবে।

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

যদি এটি কোনও বাধা হয়ে দাঁড়ায় তবে আপনি এখনও তা করতে পারেন

 std::string(a).append(" : ").append(c) ...

appendকল যুক্তি যোগ *thisএবং তারপর নিজেদের একটি রেফারেন্স ফিরে যান। সুতরাং সেখানে অস্থায়ীদের কোনও অনুলিপি করা হয় না। অথবা বিকল্পভাবে, operator+=ব্যবহার করা যেতে পারে তবে অগ্রাধিকার ঠিক করার জন্য আপনার কুৎসিত প্রথম বন্ধনী প্রয়োজন।


আমাকে stdlib বাস্তবায়নকারীদের সত্যই এটি পরীক্ষা করে দেখতে হয়েছিল। : পি libstdc++ফর operator+(string const& lhs, string&& rhs)ডু return std::move(rhs.insert(0, lhs))। তারপরে যদি উভয়ই অস্থায়ী হয় operator+(string&& lhs, string&& rhs)তবে lhsএর যথেষ্ট পরিমাণের উপলব্ধ থাকলে কেবল তা সরাসরি হবে append()। আমি কোথায় মনে হয় এই ঝুঁকি ধীর চেয়ে হচ্ছে operator+=হলে lhs, যথেষ্ট ধারণক্ষমতা নেই তারপর যেমন ফিরে বৃক্ষের পতন rhs.insert(0, lhs)হয়, যা না শুধুমাত্র বাফার প্রসারিত & মত নতুন বিষয়বস্তু যোগ করা আবশ্যক append(), কিন্তু মূল বিষয়বস্তু বরাবর নামান প্রয়োজন rhsঠিক আছে।
আন্ডারস্কোর_

তুলনায় ওভারহেড কোনো অংশ operator+=যে operator+তাই এটি রয়েছে, এখনও একটি মান ফিরে আসবে move()যেটা প্রতীক এটি যোগ করা। তবুও, আমি অনুমান করি যে পুরো স্ট্রিংয়ের গভীর-অনুলিপি করার তুলনায় এটি মোটামুটি ছোটখাটো একটি ওভারহেড (পয়েন্টার / আকারের কয়েকটি সংকলন করা), তাই এটি ভাল!
আন্ডারস্কোর_

11

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


7
অবশ্যই এটি বেশিরভাগ ক্ষেত্রে এটির পক্ষে উপযুক্ত নয় তবে এটি তার প্রশ্নের উত্তর দেয় না।
ব্রায়ান আর। বন্ডি

1
হাঁ। আমি কেবলমাত্র "প্রোফাইল তারপর অপ্টিমাইজড" বলার বিষয়ে একমত
হয়েছি

6
প্রযুক্তিগতভাবে, তিনি জিজ্ঞাসা করেছিলেন এগুলি কি "প্রয়োজনীয়"? তারা নয়, এবং এটি সেই প্রশ্নের উত্তর দেয়।
সামান্থা ব্রানহাম

যথেষ্ট উপযুক্ত, তবে এটি অবশ্যই কিছু অ্যাপ্লিকেশনের জন্য প্রয়োজন। সুতরাং এই প্রয়োগগুলিতে উত্তরটি হ্রাস পায়: 'বিষয়গুলি নিজের হাতে নিন'
ব্রায়ান আর বন্ডি

4
@ পেস্তো প্রোগ্রামিং জগতে একটি বিকৃত ধারণা রয়েছে যে পারফরম্যান্সে কোনও গুরুত্ব আসে না এবং আমরা কেবল পুরো চুক্তিকেই উপেক্ষা করতে পারি কারণ কম্পিউটারগুলি দ্রুততর হচ্ছে। জিনিসটি হ'ল এটি কেন লোকেরা সি ++ এ প্রোগ্রাম করে এবং তাই নয় কেন তারা দক্ষ স্ট্রিং কনটেন্টেশন সম্পর্কে স্ট্যাক ওভারফ্লোতে প্রশ্ন পোস্ট করে।
মিঃফক্স

7

.NET System.Strings মতো সি ++ এর এসটিডি :: স্ট্রিং হয় চপল, সেইজন্য এবং সহজ সংযুক্তকরণের মাধ্যমে যত দ্রুত ঠিক যেমন অন্যান্য পদ্ধতি মাধ্যমে নির্মিত হতে পারে।


2
বিশেষত আপনি যদি ফলাফল শুরু করার আগে বাফারটিকে যথেষ্ট বড় করতে রিজার্ভ () ব্যবহার করেন।
মার্ক র্যানসম

আমার মনে হয় তিনি অপারেটর ++ এর কথা বলছেন। যদিও এটি একটি অবক্ষয়জনক ক্ষেত্রে, তবুও এটি সুস্পষ্ট। জেমস একটি ভিসি ++ এমভিপি ছিল তাই আমি আশা করি তার সি
+++

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

1
হাঁ। তবে তারপরে তিনি কেস অপারেটরটির জন্য জিজ্ঞাসা করলেন slow এবং এখানে অপারেটর + = খেলায় আসে। তবে আমি জেমসের উত্তরটি সামান্য সংক্ষেপে সম্মত। এটি এমন শোনাচ্ছে যা আমরা সবাই অপারেটর + ব্যবহার করতে পারি এবং এটি শীর্ষ দক্ষ: p
জোহানেস স্কাউব - লিটব

@ ব্রায়ানআর.বোন্ডিকে operator+নতুন স্ট্রিং ফিরতে হবে না। প্রবর্তকরা যদি অপারেন্ডকে যথাযথ রেফারেন্স দিয়ে পাস করে থাকে তবে এর কোনও অপারেন্ডকে পরিবর্তিত, ফিরিয়ে দিতে পারে। libstdc++ উদাহরণস্বরূপ এটি করে । সুতরাং, operator+অস্থায়ীদের সাথে কল করার সময়, এটি একই বা প্রায় ভাল পারফরম্যান্স অর্জন করতে পারে - এটির খেলাপি হয়ে দাঁড়ানোর পক্ষে যদি অন্য কোনও যুক্তি হতে পারে তবে যদি না কারও কাছে প্রমাণ হয় যে এটি কোনও বাধা চিহ্নিত করে।
আন্ডারস্কোর_

5

তার পরিবর্তে সম্ভবত স্ট্রিংস্ট্রিম?

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


2
স্ট্রিংস্ট্রিমটি ধীর গতিতে দেখুন, google.google.com/d/topic/comp.lang.c++.moderated/aiFIGb6za0w
আর্টেম জিআর

1
@ আর্টেম জিআর স্ট্রিং স্ট্রিমটি দ্রুত হতে পারে, কোডপোজেজেক্ট
//

4

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

এই জাতীয় ধারণাটি এসটিএলপোর্ট স্ট্যান্ড :: স্ট্রিং বাস্তবায়নে প্রয়োগ করা হয়েছে - যা এই নির্দিষ্ট হ্যাকের কারণে মানের সাথে খাপ খায় না।


Glib::ustring::compose()গ্লিবিমিএম বাইন্ডিং থেকে জিএলআইবি এটি করে: reserve()প্রদত্ত ফর্ম্যাট স্ট্রিং এবং ভারার্গসের উপর ভিত্তি করে চূড়ান্ত দৈর্ঘ্যটি নির্ধারণ করে এবং তারপরে append()লুপের প্রতিটি (বা এর ফর্ম্যাট প্রতিস্থাপন)। আমি আশা করি এটি কাজ করার একটি দুর্দান্ত সাধারণ উপায়।
আন্ডারস্কোর_ডে

4

std::string operator+একটি নতুন স্ট্রিং বরাদ্দ করে এবং প্রতিবার দুটি অপারেন্ড স্ট্রিং অনুলিপি করে। বহুবার পুনরাবৃত্তি করুন এবং এটি ব্যয়বহুল হয়ে যায়, হে (এন)।

std::string appendএবং operator+=অন্যদিকে, স্ট্রিংটি বৃদ্ধির জন্য প্রতিবারের মতো ক্ষমতাটিকে 50% দ্বারা বিচ্ছিন্ন করুন। যা মেমরি বরাদ্দের সংখ্যা এবং কপিরাইট অপারেশনগুলিকে উল্লেখযোগ্যভাবে হ্রাস করে, হে (লগ এন)।


কেন এটিকে নিম্নমানের করা হয়েছিল তা আমি নিশ্চিত নই। 50% চিত্রটি স্ট্যান্ডার্ড দ্বারা আবশ্যক নয়, তবে আইআইআরসি বা 100% অনুশীলনে বৃদ্ধির সাধারণ ব্যবস্থা। এই উত্তরের সমস্ত কিছু আপত্তিজনক বলে মনে হচ্ছে।
আন্ডারস্কোর_

কয়েক মাস পরে, আমি মনে করি এটি operator+এতটা সঠিক নয়, যেহেতু এটি C ++ 11 আত্মপ্রকাশের অনেক পরে লেখা হয়েছিল এবং ওভারলোডগুলি যেখানে বিদ্যমান বাফারের সাথে যুক্ত হয়ে নতুন স্ট্রিংটি সম্পূর্ণরূপে বরাদ্দ এড়াতে পারে অপারেশনগুলির মধ্যে একটি (যদিও এটির অপর্যাপ্ত ক্ষমতা থাকলে তাদের পুনর্নির্মাণ করতে হতে পারে)।
আন্ডারস্কোর_

2

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

জটিল স্টেটেন্টেশনের জন্য আমি স্ট্যান্ড :: অস্ট্রিং স্ট্রিমকে পছন্দ করি।


2

বেশিরভাগ জিনিসের মতো, কিছু না করানো ছাড়া এটি না করা সহজ।

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

আপনি যদি কোনও ফাইলে আউটপুট করতে চান তবে বড় স্ট্রিং তৈরি করে আউটপুট না করে ডেটা স্ট্রিম করুন।

আমি যদি ধীর কোড থেকে অপ্রয়োজনীয় যুক্তি মুছে ফেলি তবে আমি কখনই দ্রুত প্রয়োজনের সাথে যুক্ত করার প্রয়োজনের সন্ধান পাইনি।


2

যদি আপনি ফলাফলের স্ট্রিংয়ে স্থান প্রাক-বরাদ্দ (রিজার্ভ) করেন তবে সম্ভবত সেরা পারফরম্যান্স।

template<typename... Args>
std::string concat(Args const&... args)
{
    size_t len = 0;
    for (auto s : {args...})  len += strlen(s);

    std::string result;
    result.reserve(len);    // <--- preallocate result
    for (auto s : {args...})  result += s;
    return result;
}

ব্যবহার:

std::string merged = concat("This ", "is ", "a ", "test!");

0

অক্ষরের একটি সাধারণ অ্যারে, একটি শ্রেণীর মধ্যে এনপ্যাপুলেটেড যা অ্যারে আকার এবং বরাদ্দকৃত বাইটের সংখ্যা ট্র্যাক করে রাখে তা দ্রুততম।

কৌশলটি হ'ল শুরুতে একটি বড় বরাদ্দ।

https://github.com/pedro-vicente/table-string

benchmarks

ভিজ্যুয়াল স্টুডিও 2015, এক্স 86 ডিবাগ বিল্ড, সি ++ স্টাড :: স্ট্রিংয়ের চেয়ে বৈদেশিক উন্নতি।

| API                   | Seconds           
| ----------------------|----| 
| SDS                   | 19 |  
| std::string           | 11 |  
| std::string (reserve) | 9  |  
| table_str_t           | 1  |  

1
ওপি কীভাবে দক্ষতার সাথে যুক্ত করতে আগ্রহী std::string। তারা বিকল্প স্ট্রিং ক্লাস চাইছে না।
আন্ডারস্কোর_

0

আপনি প্রতিটি আইটেমের জন্য মেমরি সংরক্ষণ সহ এটি ব্যবহার করতে পারেন:

namespace {
template<class C>
constexpr auto size(const C& c) -> decltype(c.size()) {
  return static_cast<std::size_t>(c.size());
}

constexpr std::size_t size(const char* string) {
  std::size_t size = 0;
  while (*(string + size) != '\0') {
    ++size;
  }
  return size;
}

template<class T, std::size_t N>
constexpr std::size_t size(const T (&)[N]) noexcept {
  return N;
}
}

template<typename... Args>
std::string concatStrings(Args&&... args) {
  auto s = (size(args) + ...);
  std::string result;
  result.reserve(s);
  return (result.append(std::forward<Args>(args)), ...);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.