将对以字符串形式返回文件内容的函数执行移动语义优化或返回值优化,我会从中受益吗
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),我广泛使用它,所以我寻找优化的可能性(既不破坏"将文件内容加载到字符串中"的简单性,也不产生对其他库的额外依赖)。
我应该在这里使用move语义吗(我不太熟悉)?或者,由于编译器将执行的返回值优化,我编写它的方式接近于最佳时间?
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
应该快速确定足够处理文件的容量。
坚持原始接口,即返回字符串,无论如何都很容易移动字符串:当返回临时对象或命名变量时,将使用移动构造函数。理想情况下,也可以通过为复制省略制定可行的实现来避免移动。例如,您可以始终返回相同的对象。复制省略通常发生在没有实现右值引用的编译器或没有移动构造函数的类中。我会这样实现你的功能:
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;
}
相关文章:
- 返回值优化:显式移动还是隐式
- 使用 std::p air 进行返回值优化
- C++ 特征图3.5,特征图不使用命名返回值优化?
- 我是否正确测试了返回值优化?
- 使用std::optional时的命名返回值优化
- 找不到使保证返回值优化工作的方法
- 局部堆栈变量成员的返回值优化
- 为什么 GCC 无法优化,除非返回值有名称?
- 优化的范围检查并返回值
- 在没有返回值优化的情况下将两个对象加在一起时,将创建多少个临时对象
- 为什么三元运算符阻止返回值优化
- 实现move构造函数如何影响返回值优化
- 内存分配,用于在C 11中循环中函数的返回值:如何优化
- 我如何确定将进行返回值优化
- 返回值优化并复制C中的ELINION
- 如何使编译器不优化 getter 的返回值并使其恒定
- 为什么我在此代码中没有得到返回值优化?
- 如果二进制运算符+重载的返回值是const,它会干扰优化吗
- 了解工厂方法和静态变量赋值的返回值优化 (Visual Studio)
- 返回值优化是否需要声明一个复制构造函数