Middle
C++-ში სტრიქონებთან მუშაობის ოპტიმიზაციის რა გზები არსებობს?
sobes.tech AI
პასუხი AI-სგან
std::string_view-ის გამოყენება ხაზების გადაცემისთვის მონაცემების ასლობის გარეშე.<string>და<algorithm>ბიბლიოთეკების ალგორითმების გამოყენება (find,search) ხელით იტერაციის ნაცვლად.- წინასწარ მეხსიერების გამოყოფა
reserve-ის საშუალებით, რათა შემცირდეს გადანაწილებების რაოდენობა ხაზის გაფართოებისას. - პატარა ხაზის ოპტიმიზაციის (Small String Optimization - SSO) გამოყენება
std::string-ში (თუ კომპილატორი ახორციელებს). - დიდი რაოდენობით ხაზების სწრაფი კონკატენაციისთვის გამოიყენეთ
std::stringstreamან ეტაპობრივად დაამატეთ ერთ შედეგიან ხაზს, წინასწარ განაწილებული ადგილი. - სპეციალური ბიბლიოთეკების გამოყენება, რომლებიც ოპტიმიზირებულია კონკრეტული დავალებებისთვის (მაგალითად, რეგულარული გამოთქმები).
- ხაზების განთავსება სტატიკურ მეხსიერებაში ან პულში, რათა თავიდან აიცილოთ დინამიური გამოყოფა მუდმივ ხაზებთან მუშაობისას.
- დაბალი დონე C-სტილის ფუნქციების გამოყენება (
memcpy,memmove) დიდი მოცულობის მონაცემების ასლობისთვის, თუ ეს უსაფრთხოა და გამართლებულია.
std::string_view-ის გამოყენების მაგალითი:
#include <string>
#include <string_view>
#include <iostream>
void print_string(std::string_view sv) {
std::cout << sv << std::endl;
}
int main() {
std::string s = "Hello, world!";
print_string(s); // ასლობის გარეშე
const char* c_str = "მეორე სტრიქონი";
print_string(c_str); // ასევე ასლობის გარეშე
return 0;
}
reserve-ის გამოყენების მაგალითი:
#include <string>
#include <iostream>
int main() {
std::string s;
s.reserve(100); // წინასწარ გამოყოფილი ადგილი
for (int i = 0; i < 100; ++i) {
s += 'a'; // სიმბოლოების დამატება, ნაკლები გადანაწილება
}
std::cout << "ზომა: " << s.size() << ", მოცულობა: " << s.capacity() << std::endl;
return 0;
}
კონკატენაციის შედარება:
#include <string>
#include <sstream>
#include <iostream>
#include <chrono>
int main() {
const int count = 1000;
std::string chunk = "abc";
// `+=` ოპერატორით კონკატენაცია
auto start1 = std::chrono::high_resolution_clock::now();
std::string result1;
result1.reserve(count * chunk.size()); // ოპტიმიზაცია წინასწარ განაწილებით
for (int i = 0; i < count; ++i) {
result1 += chunk;
}
auto end1 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed1 = end1 - start1;
std::cout << "ოპერატორი += (თანხის განაწილებით): " << elapsed1.count() << " წამ" << std::endl;
// `stringstream`-ის გამოყენება
auto start2 = std::chrono::high_resolution_clock::now();
std::stringstream ss;
for (int i = 0; i < count; ++i) {
ss << chunk;
}
std::string result2 = ss.str();
auto end2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed2 = end2 - start2;
std::cout << "stringstream: " << elapsed2.count() << " წამ" << std::endl;
return 0;
}
(შენიშვნა: ამ მეთოდების შესრულების სიჩქარე შეიძლება განსხვავდებოდეს კომპილატორისა და სტანდარტული ბიბლიოთეკის მიხედვით).