为什么要按值传递string_view?为什么Visual Studio不能优化这一点?
Why pass string_view by value? And why can't Visual Studio optimize this?
根据我的直觉,我认为新string_view需要通过引用传递,因为这更有效(仅传递指针而不是完整的类(。 但是,一些来源表明最好按值传递它,避免"别名"问题。
- C++视图类型:按常量传递还是按值传递?
- https://abseil.io/tips/1
在尝试几种替代方案时,我确认了我的直觉,即如果函数只执行转发string_view(所有源代码都使用/Ox
编译(而通过引用传递会更快
例如,此代码
extern auto otherMethodByReference(const std::string_view &input) -> void;
auto thisMethodByReference(int value, const std::string_view &input) -> void
{
otherMethodByReference(input);
}
导致此程序集
00000 48 8b ca mov rcx, rdx
00003 e9 00 00 00 00 jmp ?otherMethodByReference@@YAXAEBV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z ; otherMethodByReference
虽然这段代码
extern auto otherMethodByValue(std::string_view input) -> void;
auto thisMethodByValue(int value, std::string_view input) -> void
{
otherMethodByValue(input);
}
导致此程序集
00000 48 83 ec 38 sub rsp, 56 ; 00000038H
00004 0f 10 02 movups xmm0, XMMWORD PTR [rdx]
00007 48 8d 4c 24 20 lea rcx, QWORD PTR $T1[rsp]
0000c 0f 29 44 24 20 movaps XMMWORD PTR $T1[rsp], xmm0
00011 e8 00 00 00 00 call ?otherMethodByValue@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z ; otherMethodByValue
00016 48 83 c4 38 add rsp, 56 ; 00000038H
0001a c3 ret 0
很明显,您可以看到在堆栈上创建了string_view的副本,然后传递给其他方法。
但是,我想知道,为什么编译器不对此进行优化,而只是将string_view参数直接传递给其他方法。 毕竟,在 Windows x64 ABI 中,大于寄存器大小的类的按值传递始终是通过复制堆栈上的寄存器并在正确的寄存器中传递指向它的指针来完成的。 我希望在此示例代码中,编译器只需将指针转发到下一个函数,就像在按引用传递的情况下一样。 毕竟,编译器可以看到参数的值之后没有使用,所以它不需要复制,而可以直接转发地址。
我尝试将 std::move 添加到通话中,如下所示:
auto thisMethodByValueAndMove(int value, std::string_view input) -> void
{
otherMethodByValue(std::move(input));
}
但这似乎无济于事。
Visual Studio 2017编译器无法优化这一点有什么原因吗? 其他编译器是否优化了此模式?
X64 调用约定不允许将参数分散到不同的寄存器中。 编译器可以通过 rcx 和 rdx 传递string_view,但 ABI 反对这一点。 https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019
相关文章:
- 如果我的手机是 ARMv8,为什么 Android Studio 会C++编译为 ARMv7?
- 为什么在Visual Studio的OpenCV项目中使用/MT时仍然需要dll?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- Qt - 为什么Visual Studio 2019在qml资源中添加10Mb文件后无法再编译我的项目?
- 为什么我的程序无法在GDB在线编译器/调试器或Visual Studio C++ 2019中运行
- 为什么Visual Studio没有对逻辑比较错误进行热身?
- 为什么这个错误变成(C2664错误C ++ Visual Studio)
- 为什么Visual Studio正在清除我的一串反斜杠
- 为什么只有一个库的链接器错误'multiple definitions'?在 Android Studio 中使用 CMake (3.4.1)
- 为什么Visual Studio(2017;15.7.5)不允许我更改c ++关键字颜色
- 为什么Visual Studio会以不同的方式对待我的对象
- 为什么作业提交网站的输出与Visual Studio不同
- 为什么Visual Studio 2019不支持用于减少Openmp的关键字"max"?
- Visual Studio生成"Error: uninitialized local variable 'x' "而在线编译器不会 - 为什么?
- 为什么Visual Studio允许我在模板函数中使用私有成员(C++)?
- 为什么Visual Studio无法识别is_open()功能
- 为什么要按值传递string_view?为什么Visual Studio不能优化这一点?
- 为什么我不能编译这个在Cygwin的Visual Studio中编写的C++文件?
- 为什么在Visual Studio中用c ++编写GUI应用程序的代码与控制台应用程序的代码不同?
- 为什么不按默认构造路径划分路径只是在 Visual Studio 中添加尾随分隔符?