我在2009年首先注意到GCC(至少在我的项目和我的机器上)如果我优化尺寸(-Os)而不是速度(-O2或-O3),则会产生明显更快的代码,我一直想知道为什么.
我设法创建(相当愚蠢)代码,显示这种令人惊讶的行为,并且足够小,无法在此处发布.
const int LOOP_BOUND = 200000000;
__attribute__((noinline))
static int add(const int& x, const int& y) {
return x + y;
}
__attribute__((noinline))
static int work(int xval, int yval) {
int sum(0);
for (int i=0; i<LOOP_BOUND; ++i) {
int x(xval+sum);
int y(yval+sum);
int z = add(x, y);
sum += z;
}
return sum;
}
int main(int , char* argv[]) {
int result = work(*argv[1], *argv[2]);
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果我用-Os它编译它,执行这个程序需要0.38秒,如果用-O2 …
当我启用C++ 11时,我在一个小的C++片段中发现了一个有趣的性能回归:
#include <vector>
struct Item
{
int a;
int b;
};
int main()
{
const std::size_t num_items = 10000000;
std::vector<Item> container;
container.reserve(num_items);
for (std::size_t i = 0; i < num_items; ++i) {
container.push_back(Item());
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用g ++(GCC)4.8.2 20131219(预发行版)和C++ 03,我得到:
milian:/tmp$ g++ -O3 main.cpp && perf stat -r 10 ./a.out
Performance counter stats for './a.out' (10 runs):
35.206824 task-clock # 0.988 CPUs utilized ( +- 1.23% )
4 context-switches # 0.116 K/sec ( +- 4.38% )
0 cpu-migrations …Run Code Online (Sandbox Code Playgroud) 如果下面的类不是模板,我可以简单地x在derived课堂上.但是,使用下面的代码,我必须使用this->x.为什么?
template <typename T>
class base {
protected:
int x;
};
template <typename T>
class derived : public base<T> {
public:
int f() { return this->x; }
};
int main() {
derived<int> d;
d.f();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 标题非常具有自我描述性.我已经下载了Qt Creator 2.7.0,我正在尝试编译一些基本的C++ 11代码:
int my_array[5] = {1, 2, 3, 4, 5};
for(int &x : my_array)
{
x *= 2;
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
range based for loops are not allowed in c++ 98 mode
Run Code Online (Sandbox Code Playgroud)
然而,根据这篇文章,这个版本的Qt Creator支持C++ 11.那么我该如何启用呢?
const auto&如果我想执行只读操作就足够了.但是,我已经碰到了
for (auto&& e : v) // v is non-const
Run Code Online (Sandbox Code Playgroud)
最近几次.这让我想知道:
是否有可能在一些不起眼的角落情况下,存在使用通用引用一些性能优势,相比auto&还是const auto&?
(shared_ptr是一个晦涩角落案件的嫌疑人)
更新 我在收藏夹中找到的两个示例:
迭代基本类型时使用const引用的任何缺点?
我可以使用基于范围的for循环轻松迭代地图的值吗?
请专注于一个问题:我为什么要在使用自动&&范围为基础的for循环?
服务工作者可以做什么,网络工作者不能?或相反亦然?
Web工作者似乎是服务工作者功能的一个子集.它是否正确?
那些不需要这些工具的概念不是C++ 11的一部分.
有哪些生产质量工具可用于解析源自基于模板的代码的错误消息?Eclipse-CDT支持也很不错.:)
如果我放弃C++ 11,我对C++ 98有什么选择?
相关问题:
std::chrono::duration自固定日期起如何获得?我需要这个来转换std::chrono::time_point为unix时间戳.
将代码插入XXX
auto unix_epoch_start = XXX;
auto time = std::chrono::system_clock::now();
auto delta = time - unix_epoc_start;
auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(delta).count();
Run Code Online (Sandbox Code Playgroud)
我知道time_point有一种方法,time_since_epoch()但不能保证这与unix时代(1970年1月1日00:00:00 UTC)相同.
std::lower_bound()如果我将一对红黑树迭代器(set::iterator或map::iterator)传递给它,我总是假设以对数时间运行.std::lower_bound()在这种情况下,至少在libstdc ++实现中,我必须自己两次燃烧以注意在O(n)时间运行.据我所知,该标准没有红黑树迭代器的概念; std::lower_bound()将它们视为双向迭代器,advance并将它们视为线性时间.我仍然没有看到任何理由为什么实现无法为红黑树迭代器创建特定于实现的迭代器标记, 并且lower_bound()如果传入的迭代器恰好是红黑树迭代器则调用专用.
是否有任何技术原因std::lower_bound()不专门用于红黑树迭代器?
更新:是的,我知道查找成员函数,但它不是重点.(在模板化代码中,我可能无法访问容器或仅在容器的一部分上工作.)
赏金到期后:我发现Mehrdad和Yakk的答案最有说服力.我也无法决定; 我正在给予Mehrdad赏金并接受Yakk的回答.
而不是写town->first我想写town->name.内联命名访问器(重命名地图迭代器和命名std :: pair成员的第一个和第二个)是我到目前为止找到的最佳解决方案.我对命名访问器的问题是类型安全性的丢失:
pair<int,double>可能是指struct { int index; double value; }或者struct { int population; double avg_temp; }.任何人都可以提出一个简单的方法,也许类似于特征?
我经常想从一个函数返回一对或一个元组,struct city { string name; int zipcode; }每次引入一个类似的新类型和它的ctor 是非常累人的.我很高兴了解boost和C++ 0x但我需要一个没有提升的纯C++ 03解决方案.
更新
Re andrewdski的问题:是的,一个(假设的)语法就像pair<int=index, double=value>创建一个不同的类型来pair<int=population, double=avg_temp>满足你的要求.我甚至不介意实现一个自定义的对/元组模板类ONCE,只是当我需要一个新类型时,只是将'name traits'模板参数传递给它.我不知道'名称特征'会是什么样子.也许这是不可能的.
c++ ×9
c++11 ×6
performance ×3
stl ×3
templates ×3
gcc ×2
algorithm ×1
c++-chrono ×1
c++-faq ×1
for-loop ×1
html ×1
inheritance ×1
javascript ×1
qt ×1
traits ×1
typedef ×1
vector ×1
w3c ×1
web-worker ×1
x86-64 ×1