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

使用C11的“自动”能提高性能吗?

禄源
2023-03-14

我明白为什么C 11中的自动类型提高了正确性和可运维性。我读到它也可以提高性能(赫伯·萨特的《几乎总是自动》),但我错过了一个很好的解释。

  • auto如何提高性能

共有3个答案

艾谦
2023-03-14
匿名用户

有两类。

auto可以避免类型擦除。有不可命名的类型(如lambdas)和几乎不可命名的类型(如std::bind或其他表达式模板之类的东西的结果)。

如果没有auto,您最终必须键入擦除数据的内容,例如std::function。类型擦除有成本。

std::function<void()> task1 = []{std::cout << "hello";};
auto task2 = []{std::cout << " world\n";};

task1具有类型擦除开销——可能的堆分配、难以将其内联以及虚拟函数表调用开销<代码>任务2没有。lambda需要自动或其他形式的类型推断来存储,而不需要类型擦除;其他类型可能非常复杂,以至于他们只在实践中需要它。

第二,你可能会把类型弄错。在某些情况下,错误的类型看似完美,但会导致复制。

Foo const& f = expression();

如果expression()

程序员可能是指Bar const

最常见的例子是*std::映射的类型

Barry和KerrekSB都在他们的回答中首先阐明了这两个原则。这只是试图在一个答案中突出这两个问题,措辞针对问题,而不是以实例为中心。

郤浩慨
2023-03-14

由于auto推导初始化表达式的类型,因此不涉及类型转换。与模板算法相结合,这意味着您可以得到比自己创建类型更直接的计算——尤其是在处理无法命名其类型的表达式时!

一个典型的例子来自(ab)使用std::function

std::function<bool(T, T)> cmp1 = std::bind(f, _2, 10, _1);  // bad
auto cmp2 = std::bind(f, _2, 10, _1);                       // good
auto cmp3 = [](T a, T b){ return f(b, 10, a); };            // also good

std::stable_partition(begin(x), end(x), cmp?);

使用cmp2cmp3,整个算法可以内联比较调用,而如果构造一个std::function对象,不仅调用不能内联,而且还必须通过函数包装器内部类型擦除的多态查找。

这个主题的另一个变体是,你可以说:

auto && f = MakeAThing();

这始终是一个引用,绑定到函数调用表达式的值,并且从不构造任何其他对象。如果您不知道返回值的类型,可能会被迫通过t之类的方式构造一个新对象(可能是临时对象)

赫连泰宁
2023-03-14

auto可以通过避免无提示隐式转换来提高性能。我发现一个引人注目的例子如下。

std::map<Key, Val> m;
// ...

for (std::pair<Key, Val> const& item : m) {
    // do stuff
}

看到虫子了吗?在这里,我们认为我们通过const引用优雅地获取地图中的每个项目,并使用新的表达式范围来明确我们的意图,但实际上我们复制了每个元素。这是因为std::map

std::pair<Key, Val> const& item = *iter;

我们必须进行类型转换,而不是对现有对象进行引用并保持不变。只要存在可用的隐式转换,您就可以对不同类型的对象(或临时对象)进行const引用,例如:

int const& i = 2.0; // perfectly OK

类型转换是允许的隐式转换,原因与您可以将const Key转换为Key相同,但是我们必须构造新类型的临时类型以允许这样做。因此,我们的循环实际上做到了:

std::pair<Key, Val> __tmp = *iter;       // construct a temporary of the correct type
std::pair<Key, Val> const& item = __tmp; // then, take a reference to it

(当然,实际上没有一个__tmp对象,它只是用来说明的,实际上未命名的临时对象只是在其生命周期内绑定到项目)。

只是换成:

for (auto const& item : m) {
    // do stuff
}

刚刚为我们保存了大量副本-现在引用的类型与初始值设定项类型匹配,因此不需要临时或转换,我们可以直接引用。

 类似资料:
  • 我对最新gcc中基于pthread和Ubuntu开发环境的线程的互斥锁和消息传递的性能感兴趣。一个很好的通用问题是用餐哲学家,每个哲学家使用lh和rh叉子与左右手邻居共享。我把哲学家的数量增加到99个,让我的四核处理器保持忙碌。 上面的代码允许我的哲学家尝试抓住他们需要的两个叉子。 上面的代码监控我的哲学家的进食或思考进度,这取决于他们是否能够保留这两个叉子。 在所有哲学家尝试自由选择后,等待所有

  • 我正在用docx4j做一些测试。我需要做的是将复杂的Word文档(2-3页的文本、表格、项目符号列表、图像)转换成XHTML。

  • 我在我的应用程序中创建了第二个DataSource。 我用HikariDataSource创建了它,因为它断开了连接,所以出现了问题。 现在它没有断开,但是很慢 我的配置如下: 爪哇: 有人能告诉我如何提高绩效吗。 它们是表的小查询,分页约为25条记录,需要4秒钟。 我观察到,查询一个select的200条记录需要46秒,而查询只需要2秒。 以前,它们是千分之一秒。 非常感谢。

  • 当我直接在Azure门户的数据资源管理器中运行以下查询时,大约需要2秒才能完成。使用DocumentDB SDK运行相同的查询时,大约需要1分钟才能完成。为什么两种方法之间的性能差距如此之大,以及如何使用SDK实现相同的性能? 我们使用的代码: 我们使用Microsoft软件包。蔚蓝色的文档数据库。2.11.2. _客户端使用ConnectionMode打开。直接和协议。Tcp协议 Request

  • 我们运行在apache kafka 0.10.0. x和Spring 3. x上,不能使用Spring kafka,因为它支持Spring框架版本4. x。 因此,我们使用原生的Kafka Producer API来生成消息。 现在我关心的是我的制片人的表现。问题是我相信有人打电话给是真正连接到Kafka broker,然后将消息放入缓冲区,然后尝试发送,然后可能会调用。 现在,KafkaProd

  • 您可以通过优化您的计算机系统、After Effects、您的项目和您的工作流程来改进性能。此处提供的某些建议不是通过提高渲染速度而是通过降低其他操作(例如,打开项目)所需的时间来改进性能的。 注意:到目前为止,用来改进总体性能的最好方法是提前规划、针对您的工作流程和输出管道运行早期测试、并确认您所提供的内容是您的客户实际需要和预期的内容。(请参阅规划您的工作。) Lloyd Alvarez 在