【发布时间】:2011-04-28 08:45:19
【问题描述】:
这是一个从缓冲源获取数据并将其发送以进行处理的片段。如果队列为空,get() 返回 null,process 方法很乐意接受 null 并且什么也不做。 编写此代码的最佳方式是什么?
something a; // any legal C++ return type...
aQueueOfSomethings g;
while (true) {
a=g.get();
process(a);
}
没有办法预测通过 get() 到达的值,它们就是它们,它们需要尽快出列并传递给 process()。
我没有看到很多浪费的努力——如果我跳过名为“a”的显式局部变量并让循环成为一个单行:
process(g.get());
g.get() 的隐式返回值仍然会分配空间,可能涉及构造函数调用等。
如果返回的东西有任何大小或复杂性,最好有一个指向它的指针而不是它的副本,并传递该指针而不是按值复制...所以我宁愿有
something *a;
g.get(a);
process(a);
而不是
something a;
a=g.get();
process(a);
我用 C++ 写了一个测试用例,尝试了两行和一行的版本,循环了 100,000,000 次。
如果 a 是一个有 4 个整数和 2 个浮点数的对象,并且 process() 方法都接触到了它们,那么两行解决方案实际上更快!如果 a 对象是单个 int,则单行版本更快。如果对象比较复杂,但是 process() 方法只触及一个值,那么单行版本更快。
对我来说最有趣的是,使用 g++ 编译器,Mac OS X 10.5.8,-O 第一级优化开关导致相同的、更快的操作,同时具有 1 行和 2 行版本。
除了让编译器优化之外,两个方法都只有一行,没有显式的中间变量,并且通过引用传递以避免复制,有什么通常可以让它运行得更快吗?我觉得我错过了一些明显的东西。
【问题讨论】:
-
“啊,动力!?”很高兴你问。这是一个面试问题,在进入 2 行表格后,我说我认为我们已经完成了。与我交谈的人非常惊讶,并坚定地说我错过了一些东西。很明显的事情,她不会告诉我那是什么,我应该考虑一下。所以我有。 (很明显,我没有给人留下深刻的印象并且不再是该工作的候选人......)这就是为什么我想知道单行版本 - 以及为什么我制作和测量测试用例。优化解决了它。也许她的意思是我将界面更改为传递引用。
标签: c++ pass-by-reference pass-by-value temporary