我是否会受益于应用移动语义或 return-value-optimization 将对 returns 文件内容作为字符串的函数执行?
Would I benefit from applying move semantic or return-value-optimization will be performed for function that returns file content as string?
我有一些 load(..)
方法可以将文件内容加载到 std::wstring
。它通常处理相当大的文件(最多几 MB)并且我广泛使用它所以我寻找优化的可能性(不破坏 "load the file content into string" 的简单性并且不产生对其他库的额外依赖)。
这里要不要用move semantic(我不是很熟)?或者我写它的方式接近于最优化的时间,因为编译器将执行 return-value-optimization?
inline static std::wstring load(std::wstring filePath) {
std::wifstream file(filePath.c_str());
if(file){
std::wstring fileString;
fileString.reserve((size_t)file.tellg());
file.seekg(0);
while(!file.eof()){
fileString += file.get();
}
file.close();
return fileString;
}
file.close();
ERROR_HANDLE(L"File could not be open:\n" + filePath);
return L"";
}
实现的代码将继续为存储文件内容的字符串分配新内存。对于引用的字符串大小,实际分配开销可能可以忽略不计。然而,很有可能内存没有映射到任何缓存,访问它可能相应地相对昂贵:已经映射的内存需要被驱逐。假设调用 load()
的代码本质上只是处理字符串的内容,保持相同的字符串可能具有性能优势。相应的实现可能如下所示:
inline bool load(std::string const& path, std::wstring& content) {
std::wifstream in(path.c_str());
if (in) {
content.assign(std::istreambuf_iterator<wchar_t>(in),
std::istreambuf_iterator<wchar_t>());
return true;
}
else {
return false;
}
}
不需要 reserve()
内存,因为 content
应该可以快速确定足以处理文件的容量。
坚持使用原始界面,即 returning 一个字符串,将很容易 移动 字符串:当 returning 一个临时对象或将使用一个命名变量和一个移动构造函数。理想情况下,通过为 copy-elision 布置可行的实现,也可以避免移动。例如,您始终可以 return 同一个对象。即使对于未实现右值引用的编译器或没有移动构造函数的 类,复制省略通常也会发生。我会像这样实现你的功能:
inline std::wstring load(const std::string& path) {
std::wifstream in(path.c_str());
std::wstring result;
if (in) {
// possibly result.reserve() capacity
result.assign(std::istreambuf_iterator<wchar_t>(in),
std::istreambuf_iterator<wchar_t>());
}
return result;
}
我有一些 load(..)
方法可以将文件内容加载到 std::wstring
。它通常处理相当大的文件(最多几 MB)并且我广泛使用它所以我寻找优化的可能性(不破坏 "load the file content into string" 的简单性并且不产生对其他库的额外依赖)。
这里要不要用move semantic(我不是很熟)?或者我写它的方式接近于最优化的时间,因为编译器将执行 return-value-optimization?
inline static std::wstring load(std::wstring filePath) {
std::wifstream file(filePath.c_str());
if(file){
std::wstring fileString;
fileString.reserve((size_t)file.tellg());
file.seekg(0);
while(!file.eof()){
fileString += file.get();
}
file.close();
return fileString;
}
file.close();
ERROR_HANDLE(L"File could not be open:\n" + filePath);
return L"";
}
实现的代码将继续为存储文件内容的字符串分配新内存。对于引用的字符串大小,实际分配开销可能可以忽略不计。然而,很有可能内存没有映射到任何缓存,访问它可能相应地相对昂贵:已经映射的内存需要被驱逐。假设调用 load()
的代码本质上只是处理字符串的内容,保持相同的字符串可能具有性能优势。相应的实现可能如下所示:
inline bool load(std::string const& path, std::wstring& content) {
std::wifstream in(path.c_str());
if (in) {
content.assign(std::istreambuf_iterator<wchar_t>(in),
std::istreambuf_iterator<wchar_t>());
return true;
}
else {
return false;
}
}
不需要 reserve()
内存,因为 content
应该可以快速确定足以处理文件的容量。
坚持使用原始界面,即 returning 一个字符串,将很容易 移动 字符串:当 returning 一个临时对象或将使用一个命名变量和一个移动构造函数。理想情况下,通过为 copy-elision 布置可行的实现,也可以避免移动。例如,您始终可以 return 同一个对象。即使对于未实现右值引用的编译器或没有移动构造函数的 类,复制省略通常也会发生。我会像这样实现你的功能:
inline std::wstring load(const std::string& path) {
std::wifstream in(path.c_str());
std::wstring result;
if (in) {
// possibly result.reserve() capacity
result.assign(std::istreambuf_iterator<wchar_t>(in),
std::istreambuf_iterator<wchar_t>());
}
return result;
}