当前位置: 首页 > 知识库问答 >
问题:

具有自动返回类型的特征转换-效率低于显式返回类型?

钱运浩
2023-03-14

当将向量整数(即,Eigen::VectorXi)强制转换为双精度向量,然后对该双精度向量进行操作时,如果强制转换的返回类型为auto,则生成的程序集将大不相同。

换言之,使用:

    Eigen::VectorXi int_vec(3);
    int_vec << 1, 2, 3;

    Eigen::VectorXd dbl_vec = int_vec.cast<double>();

相比于:

    Eigen::VectorXi int_vec(3);
    int_vec << 1, 2, 3;

    auto dbl_vec = int_vec.cast<double>();

下面是戈德波特的两个例子:

返回类型:https://godbolt.org/z/0FLC4r

自动返回类型:https://godbolt.org/z/MGxCaL

在这里使用auto返回有什么后果?我原以为避免复印会更有效率,但现在我不确定。

共有1个答案

方恺
2023-03-14

事实上,在问题中的代码中,您避免了一个副本(事实上,在使用dbl_vec之前,它本质上是一个noop)。然而,在Godbolt上的代码中,您遍历原始的int_vec并评估dbl_vec至少两次,可能是三次:

max + std::log((dbl_vec.array() - max)
^^^             ^^^^^^^           ^^^

我不确定对max的两个调用是否折叠为临时调用。我希望如此。

在任何情况下,kmdreko都是正确的,您应该避免将auto与Eigen一起使用,除非您确切知道自己在做什么。在这种情况下,auto是一个表达式模板,在使用之前不会进行计算。如果您多次使用它,那么它将被多次评估。如果评估很昂贵,那么由于不使用副本而节省的成本(附带利息)将损失在额外的评估时间上。

 类似资料:
  • 我为协变返回类型的继承创建了一个小示例。基本上有三种不同的类别: 主应用程序: BaseManager: 鸟经理: 当我重写方法以返回时,为什么我需要将类型转换为? 我使用过的重写方法在返回类型上会有所不同吗?作为参考。 编辑: 我有不同的子模型,它们都继承自。所有模型都允许存在一次。我尝试将这些模型添加到列表中,而不是对每个模型使用单例。使用,我想得到实际的模型。也许我得考虑太多了。

  • 下面的代码来自一个名为ButterKnife的Android库。我正在弄清楚它是怎么工作的。 我试图重新创建此函数的行为: 和用法: 但是异常并非永远不会被捕获,而是在调用方法时在行中抛出。为什么? 还有,这到底是如何工作的?该方法如何知道要转换到什么?

  • 假设我已经包装了我的C类和,并且可以通过SWIG生成的模块从Python访问它们: 在Python中,我创建了面向用户的类,它是一个浅层代理,主要添加docstring,并允许IDE对参数名称进行制表符补全: 问题在于,返回类型为,它没有docstring,也不显示参数名称(swig将所有参数公开为)。相反,我希望它提供我自己的浅代理

  • 我尝试通过methodhandles将方法链接在一起,其中一些方法来自泛型类型。如果函数返回泛型类型,我必须为MethodType指定Object.Class,但我看不到将其转换回泛型类型参数类型的简单方法。在大多数情况下,这没有问题,因为invoke似乎自动转换它们,但我必须创建mhs,它可以用InvokeExact运行。难道没有简单的方法使用MethodHandles进行强制转换吗? 我的测试

  • 我有一个函数从服务器获取一个文件并解析了该文件,我正在使用一个具有如下完成处理程序的函数来获取该文件 但是,当我尝试使用该函数时 我得到无法将类型“()”的返回表达式转换为返回类型“String”的错误。 知道我做错了什么吗?

  • 我试图用Java中的一个通用返回类型来实现< code >命令模式。 在SO上查看了这个答案后,我创建了一个类(接口),如下所示: 然而,Eclipse一直抱怨: SearchResultsPage 类型的方法 execute(ArrayList, T) 必须重写或实现超类型方法 但当我点击 在超类型命令中创建 execute() Eclipse自动生成方法<code>T execute(Arra