- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我已经为将新元素添加到我知道其大小的 vector 做了一个小基准。
代码:
struct foo{
foo() = default;
foo(double x, double y, double z) :x(x), y(y), z(y){
}
double x;
double y;
double z;
};
void resize_and_index(){
std::vector<foo> bar(1000);
for (auto& item : bar){
item.x = 5;
item.y = 5;
item.z = 5;
}
}
void reserve_and_push(){
std::vector<foo> bar;
bar.reserve(1000);
for (size_t i = 0; i < 1000; i++)
{
bar.push_back(foo(5, 5, 5));
}
}
void reserve_and_push_move(){
std::vector<foo> bar;
bar.reserve(1000);
for (size_t i = 0; i < 1000; i++)
{
bar.push_back(std::move(foo(5, 5, 5)));
}
}
void reserve_and_embalce(){
std::vector<foo> bar;
bar.reserve(1000);
for (size_t i = 0; i < 1000; i++)
{
bar.emplace_back(5, 5, 5);
}
}
然后我调用了每个方法 100000 次。
结果:
resize_and_index: 176 mSec
reserve_and_push: 560 mSec
reserve_and_push_move: 574 mSec
reserve_and_embalce: 143 mSec
调用代码:
const size_t repeate = 100000;
auto start_time = clock();
for (size_t i = 0; i < repeate; i++)
{
resize_and_index();
}
auto stop_time = clock();
std::cout << "resize_and_index: " << (stop_time - start_time) / double(CLOCKS_PER_SEC) * 1000 << " mSec" << std::endl;
start_time = clock();
for (size_t i = 0; i < repeate; i++)
{
reserve_and_push();
}
stop_time = clock();
std::cout << "reserve_and_push: " << (stop_time - start_time) / double(CLOCKS_PER_SEC) * 1000 << " mSec" << std::endl;
start_time = clock();
for (size_t i = 0; i < repeate; i++)
{
reserve_and_push_move();
}
stop_time = clock();
std::cout << "reserve_and_push_move: " << (stop_time - start_time) / double(CLOCKS_PER_SEC) * 1000 << " mSec" << std::endl;
start_time = clock();
for (size_t i = 0; i < repeate; i++)
{
reserve_and_embalce();
}
stop_time = clock();
std::cout << "reserve_and_embalce: " << (stop_time - start_time) / double(CLOCKS_PER_SEC) * 1000 << " mSec" << std::endl;
我的问题:
基准测试条件:
另一台机器(通过 horstling ):
VS2013、Win7、至强 1241 @ 3.5 Ghz
resize_and_index: 144 mSec
reserve_and_push: 199 mSec
reserve_and_push_move: 201 mSec
reserve_and_embalce: 111 mSec
最佳答案
首先,reserve_and_push 和 reserve_and_push_move 在语义上是等价的。您构造的临时 foo 已经是一个右值(已经使用了 push_back 的右值引用重载);将它包装在一个移动中不会改变任何东西,除了可能会使编译器的代码模糊不清,这可以解释轻微的性能损失。 (虽然我认为它更可能是噪音。)此外,您的类(class)具有相同的复制和移动语义。
其次,如果将循环体写为 resize_and_index 变体可能会更优化
item = foo(5, 5, 5);
虽然只有分析才能证明这一点。关键是编译器可能会为三个单独的分配生成次优代码。
第三,你也应该试试这个:
std::vector<foo> v(100, foo(5, 5, 5));
第四,这个基准对编译器非常敏感,因为编译器意识到这些函数实际上没有做任何事情,只是简单地优化了它们的完整主体。
现在进行分析。请注意,如果您真的想知道发生了什么,则必须检查编译器生成的程序集。
第一个版本执行以下操作:
这里的主要问题是编译器是否意识到第二步中的构造函数是空操作并且它可以省略整个循环。组装检查可以证明这一点。
第二个和第三个版本执行以下操作:
编译器这里有很大的优化空间。如果它将所有操作内联到同一个函数中,它就会意识到大小检查是多余的。然后它可以意识到你的移动构造函数不能抛出,这意味着整个循环是不可中断的,这意味着它可以将所有增量合并到一个赋值中。如果它不内联 push_back,它必须将临时文件放在内存中并传递对它的引用;它可以通过多种方式对此进行特殊处理以提高效率,但不太可能。
但除非编译器执行其中的某些操作,否则我预计此版本会比其他版本慢很多。
第四个版本做了以下事情:
这和前面的类似,有两点不同:第一,MS标准库实现push_back的方式,它要检查传递的引用是否是vector本身的引用;这大大增加了函数的复杂性,抑制了内联。 emplace_back 没有这个问题。其次,emplace_back 获取三个简单的标量参数而不是对堆栈对象的引用;如果函数没有被内联,则传递的效率要高得多。
除非您专门使用 Microsoft 的编译器,否则我强烈建议您与其他编译器(及其标准库)进行比较。我还认为我建议的版本会打败你们所有的四个版本,但我还没有对此进行分析。
最后,除非代码真的对性能很敏感,否则你应该编写最可读的版本。 (这是我的版本获胜的另一个地方,IMO。)
关于c++ - 已知大小时向 vector 添加元素的基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34084172/
我有一个如下所示的目录树,我需要使用 Jenkins 将完整的结构上传到 Artifactory。现在,我找不到一种方法将属性分配给“德里”下的所有文件,使其具有 Continent(property
我想编写一个扩展,在加载特定 URL 时将 div 元素添加到页面(例如,当 url 为 http://www....&q=car&aq 时,我希望将包含“car”的 div 元素添加到网页) 我已经
从我的服务器应用程序(Spring Boot 应用程序)使用 apns 推送证书发送推送通知时被卡住了。苹果讨论 here关于我们如何发送带有证书的推送的概述,但没有关于 TLS 通信的技术细节(特别
我有一个具有相同类的 div 列表。每个 div 包含其他 div,.header、.body、.footer。当我将鼠标悬停在一个 div 内的某个元素上时,例如 .header,我需要在同一 di
如何在使用 netbeans 时将数据添加到 JTable。它的后台代码中的 Netbeans 是这样的: jTable1 = new javax.swing.JTable(); jTable1.se
我正在使用 plyr作为 HTML5 视频标签的包装器并使用 Hls.js 流式传输我的 .m3u8 视频。 我在 plyr 上解决了很多问题以启用质量选择器,并遇到了多个 PR,这些 PR 有这个问
我使用 Microsoft bot Framework 并将其部署到 Web Chat,我的 bot 以所需的正确格式打印消息并带有换行符“\n\n”,然后我使用以下教程 https://github
我已经在我的项目中添加了用于 Selenium 测试的 chromedriver 选项,但我不明白 edgedriver 的适当方法。我已经尝试了所有的可能性。 有人可以帮我吗? 谢谢你。
我需要能够在 ckeditor 的工具栏上添加一个下拉列表或按钮,以弹出一个列表,当单击一个列表项时,该列表项的文本将被添加到 ckeditor 的内容中 我还需要能够改变那个列表的内容,比如有一个功
当 bootstrap 3 collapsible 折叠时,如何向 div 添加类?我需要一个在 div 折叠时添加类 darken 的代码。当一个可折叠的关闭时,类 darken 应该被删除 #co
我在 Google map 中有很多标记(大约 3000 个),它们在弹出窗口中带有图标和高级详细信息。这就是为什么 map 打开很晚,所有标记加载也很晚。因为我从数据库加载所有标记列表并使用 for
我有一个我称之为资源的表,当用户连续单击按钮时,我想在 jquery 对话框中显示特定记录。 在我做的表中: "ui-button ui-state-default ui-corner-all", :
我正在使用第三方发送电子邮件,他们允许我通过向通过他们发送的电子邮件添加标题来对我的电子邮件进行分类。 是否可以在异常(exception)电子邮件发送前添加标题?或者至少,我将通过捕获中间件中的异常
我有一个页面,其中包含链接到页面适当部分的 anchor 。我想知道是否有人对如何在单击链接时以及当窗口/页面使用 jQuery 滚动到适当的 div 时切换 anchor 链接的类有任何建议? 例如
我正在使用 HTML、PHP 和 JS 创建一个报告网站。我有几张 table 正在展示。在每个表中有多个行 tr 和许多列 td。我对其进行了设置,以便当我单击其中一个 tr 时,它会获得 sele
我使用 UIWebView 以这样的缅甸字体显示搜索测试 NSString *googleText = @"မြန်မာဘာသာ"; NSString *googleLink = [N
在将其添加为包装器 UIView 的 subview 之前,我尝试使用 Autolayout 创建以下设置到我的 UITableView。 到目前为止,我正在使用以下内容,但一点运气都没有。据我所知,
在迭代 map 时,向 map 添加/删除元素是否安全?请看下面的伪代码: //Pseudo Code //test is a global variable
我编写了一个名为 dragscroll 的 Angular Directive(指令),它根据在 Canvas 上的拖动向右或向左滚动水平溢出元素。 请引用这个fiddle How it works:
在我的 meteor 应用程序中,我的 css 中有以下规则: body { background: #ddd url(../img/bg.png); padding-top: 120
我是一名优秀的程序员,十分优秀!