Std :: স্ট্রিংয়ের সি_স্ট্রি () থেকে আমরা কোন কার্যকারিতা আশা করতে পারি? সবসময় ধ্রুবক সময়?


13

আমি ইদানীং কিছু প্রয়োজনীয় অপ্টিমাইজেশন করছি। একটি জিনিস যা আমি করছি তা হ'ল কিছু অস্ট্রিংস স্ট্রিম -> স্প্রিন্টফগুলি পরিবর্তন করা। আমি এসডি স্টাইল অ্যারে, স্টাড স্ট্রিংয়ের একগুচ্ছ স্প্রিন্টফিং করছি la

char foo[500];
sprintf(foo, "%s+%s", str1.c_str(), str2.c_str());

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

উত্তর:


9

যদি আমি মনে করি, মানকটি string::c_str()সন্তুষ্টিকর বেশ কিছু ফিরিয়ে দিতে দেয় :

  • স্ট্রিং এবং সমাপ্তির সামগ্রীর জন্য স্টোরেজ যা যথেষ্ট পরিমাণে বড় NULL
  • প্রদত্ত stringঅবজেক্টের কোনও অ-কনস্ট্যান্ট সদস্য না বলা পর্যন্ত অবশ্যই বৈধ হওয়া উচিত be

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

সম্পর্কিত নোটে, যদি স্ট্রিং ফর্ম্যাটিং কর্মক্ষমতা সীমাবদ্ধ করে; বুস্ট.ফিনিক্সের মতো কোনও কিছুর সাথে একেবারে প্রয়োজন না হওয়া পর্যন্ত আপনি মূল্যায়ন স্থগিত করে আরও ভাল ভাগ্য পেতে পারেন ।

Boost.Format আমি বিশ্বাস করি যে ফলাফল না আসা পর্যন্ত ফর্ম্যাটটি অভ্যন্তরীণভাবে স্থগিত করে এবং আপনি একই ফর্ম্যাট অবজেক্টটি বারবার বিন্যাস ছাড়াই বিন্যাসের স্ট্রিংটি ব্যবহার করতে পারেন, যা আমি উচ্চ-ফ্রিকোয়েন্সি লগিংয়ের জন্য একটি উল্লেখযোগ্য পার্থক্য খুঁজে পেয়েছি।


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

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

Boost.Formatঅভ্যন্তরীণভাবে স্ট্রিমগুলির মধ্য দিয়ে যায় যা অভ্যন্তরীণভাবে sprintfবরং বড় ওভারহেড দিয়ে শেষ হয়। ডকুমেন্টেশন বলে যে এটি সমতল থেকে প্রায় 8 গুণ ধীর sprintf। আপনি যদি পারফরম্যান্স এবং টাইপ-সুরক্ষা চান তবে চেষ্টা করুন Boost.Spirit.Karma
জানু হুডেক

Boost.Spirit.Karmaপারফরম্যান্সের জন্য একটি ভাল টিপ, তবে সাবধান থাকুন যে এর প্রচলিত পৃথক পদ্ধতি রয়েছে যা বিদ্যমান printfশৈলী কোড (এবং কোডার) মানিয়ে নেওয়ার পক্ষে কৌশলপূর্ণ হতে পারে । আমি বেশিরভাগ ক্ষেত্রেই আটকেছি Boost.Formatকারণ আমাদের I / O অবিচ্ছিন্ন; তবে একটি বড় কারণ হ'ল আমি আমার সহকর্মীদের এটিকে ধারাবাহিকভাবে ব্যবহার করতে রাজি করতে পারি (এখনও কোনও ostream<<ওভারলোড সহ যে কোনও ধরণের মঞ্জুরি দেয় - যা .c_str()বিতর্ককে সুন্দরভাবে সরিয়ে দেয় ) কর্মফলন সংখ্যাগুলি।
মূল্য

23

সি ++ 11 স্ট্যান্ডার্ডে (আমি এন 3290 সংস্করণটি পড়ছি), অধ্যায় 21.4.7.1 সি_এসটার () পদ্ধতি সম্পর্কে কথা বলে:

const charT* c_str() const noexcept; const charT* data() const noexcept;

রিটার্নস: একটি পয়েন্টার পি যেমন পি + i == & অপারেটর প্রতিটি আইতে [0, আকার ()]।
জটিলতা: ধ্রুবক সময়।
প্রয়োজনীয়: প্রোগ্রামটি অক্ষরের অ্যারেতে সঞ্চিত কোনও মান পরিবর্তন করবে না।

সুতরাং, হ্যাঁ: ধ্রুবক সময় জটিলতা মান দ্বারা গ্যারান্টিযুক্ত।

আমি স্রেফ সি ++ 03 স্ট্যান্ডার্ড পরীক্ষা করেছি এবং এর কোনও প্রয়োজনীয়তা নেই বা এটি জটিলতাও বলে।


8

তত্ত্বের ক্ষেত্রে সি ++ 03 এর প্রয়োজন হয় না, এবং সেইজন্য স্ট্রিংটি চরের অ্যারে হতে পারে যেখানে নাল টার্মিনেটরের উপস্থিতি কেবল c_str () বলা হওয়ার সময় যুক্ত করা হয়। এটির পুনঃনির্মাণের প্রয়োজন হতে পারে (অভ্যন্তরীণ ব্যক্তিগত পয়েন্টার হিসাবে এটি ঘোষণা করা হলে এটি কনস্ট-নেস লঙ্ঘন করে না mutable)।

সি ++ ১১ টি আরও কঠোর: এটির জন্য সময় ব্যয় প্রয়োজন, তাই কোনও স্থান পরিবর্তন করা যায় না এবং অ্যারেটি সর্বদা নালটি শেষ পর্যায়ে সঞ্চয় করতে যথেষ্ট প্রশস্ত থাকতে হবে। c_str () নিজেই, ptr[size()]='\0'নালটি সত্যই উপস্থিত থাকার বিষয়টি নিশ্চিত করতে এখনও " " করতে পারে। পরিসর [0..size())পরিবর্তন না হওয়ায় এটি অ্যারের কনস্ট্যান্ট নেস লঙ্ঘন করে না ।

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