有两种做法的共同习惯,如下列情况?
for ( int i = 0; i < num_pairs; i++ ) {
cards.push_back( Card(i) );
cards.push_back( Card(i) );
}
我觉得有一种更清晰的方法,就是引入一个从0到1计数的新循环变量,特别是因为除了计数之外它没有被使用。
for ( int i = 0; i < num_pairs; i++ )
for ( int j = 0; j < 2; j++ )
cards.push_back( Card(i) );
(Card
只是我编写的一些课程,与问题无关。)
答案 0 :(得分:10)
您可能希望使用fill_n
<algorithm>
功能
for ( int i = 0; i < num_pairs; i++ )
std::fill_n(std::back_inserter(cards), 2, Card(i));
答案 1 :(得分:6)
就我个人而言,我会留下它是怎么回事。它看起来干净,易于理解,而且非常易读。只需留下评论,提及你为什么要这样做两次(但无论如何都会这样做)。
答案 2 :(得分:5)
我有一些建议。有关我的建议,请参阅 last :
在我看来insert(it,
N
, value)
击败std::fill_n
:
for ( int i = 0; i < num_pairs; i++ ) {
cards.insert(cards.end(), 2, Card(i) );
}
如果订单不重要,您只需生成一次卡片,然后在之后复制
std::copy(cards.begin(), cards.end(), std::back_inserter(cards));
使用脏lambda和整数除法技巧。 警告这是过早优化的标志:没有充分理由降低可读性。
std::vector<Card> cards(num_pairs * 2);
int i = 0;
std::generate_n(cards.begin(), num_pairs, [&i] () { return Card(i++/2); });
(假设Card
默认可构建。如果不是,请使用cards.back_inserter()
)
以下在表现和意图表达方面取得胜利:
std::vector<Card> cards;
cards.reserve(num_pairs*2);
for (int i = 0; i < num_pairs; ++i)
{
cards.emplace_back(i);
cards.emplace_back(i);
}
答案 3 :(得分:1)
你正确使用将内部循环扩展为语句,因为使用另一个循环只有2次迭代会对性能造成不利影响。由于频繁jumps
,第二个(嵌套循环)将执行缓慢。是否会有明显的差异完全取决于num_pairs
。
所以第一个对性能更好(但是增益可能是微不足道的)。这种扩展循环在编译器的术语中称为loop unwinding/unrolling
。但是,这个术语不是在编程级别使用,因为通常只有编译器才能使代码更快。 Idioms
肯定design notions
可帮助程序员更好地编写&amp;高效的代码,更好地理解语言。
答案 4 :(得分:1)
如果你想经常这样做,写一点实用功能:
template<class F>
void repeat(unsigned times, F callback) {
while (times--) callback();
}
// ...
for (int i = 0; i < num_pairs; i++) {
repeat(2, [&] { cards.push_back(Card(i)); });
}
我在Ideone上写了一个例子。
您的第一种方法可能会让您未来的代码读者感到困惑。他们可能会认为代码偶然出现了两次。使用这样的函数可以避免这种混乱。
即使&gt;表现也会非常小。 0,因为编译器可能内联函数并完全优化小times
'的循环。如果您担心性能,请首先进行基准测试。