src: use ostringstream instead of string in FromFilePath()#50253
src: use ostringstream instead of string in FromFilePath()#50253pluris wants to merge 1 commit intonodejs:mainfrom
FromFilePath()#50253Conversation
|
Review requested:
|
|
What is the performance impact of the new proposed change? Did you had any chance to benchmark it? |
|
I ran #include <iostream>
#include <chrono>
#include <sstream>
std::string FromFilePath1(const std::string_view file_path) {
std::string escaped_file_path;
for (size_t i = 0; i < file_path.length(); ++i) {
escaped_file_path += file_path[i];
if (file_path[i] == '%') escaped_file_path += "25";
}
return escaped_file_path;
}
std::string FromFilePath2(const std::string_view file_path) {
std::ostringstream escaped_file_path;
for (size_t i = 0; i < file_path.length(); ++i) {
escaped_file_path << file_path[i];
if (file_path[i] == '%') escaped_file_path << "25";
}
return escaped_file_path.str();
}
int main() {
const std::string_view sample_url= "https://nodejs.org/en/blog/";
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
for (int i = 0;i < 1000000;i++)
FromFilePath1(sample_url);
std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;
std::cout << "result 1 : " << sec.count() <<" seconds"<< std::endl;
// Prints : result 1 : 1.63845 seconds
start = std::chrono::system_clock::now();
for (int i = 0;i < 1000000;i++)
FromFilePath2(sample_url);
sec = std::chrono::system_clock::now() - start;
std::cout << "result 2 : " << sec.count() <<" seconds"<< std::endl;
// Prints : result 2 : 1.17444 seconds
return 0;
} |
|
I ran my own benchmarks. Please see my blog post: For processing strings, streams in C++ can be slow Here is the gist:
I understand that there has been performance engineering guided by the belief that streams in C++ are efficient. My recommendation is to re-assess this belief and conduct benchmarks. In fact, it is entirely possible that removing streams where they have been added could be a strategy to improve performance. For benchmarking, I recommend using relatively large inputs. Here is why: Benchmarking is hard: processors learn to predict branches. |
|
@lemire Thanks for the good information. This |
When performing string concatenation operations, it is more advantageous in terms of performance to use
std::ostringstreamrather thanstd::string. This approach is also used elsewhere, such asdebug_utilsandnode_errors.Refs: #46410