我目前正在使用一个大容器,我需要迭代它来做很多事情。以下哪个被认为是更好的风格?
a) 大循环:
for (container::iterator it = myContainer.begin(); it < myContainer.end(); ++it) {
// do thing a with *it
// do thing d with *it
// do thing c with *it
// do thing b with *it
}
Run Code Online (Sandbox Code Playgroud)
b) 小循环:
for (container::iterator it = myContainer.begin(); it < myContainer.end(); ++it) {
// do thing a with *it
}
for (container::iterator it = myContainer.begin(); it < myContainer.end(); ++it) {
// do thing b with *it
}
for (container::iterator it = myContainer.begin(); it < myContainer.end(); ++it) {
// do thing c with *it
}
for (container::iterator it = myContainer.begin(); it < myContainer.end(); ++it) {
// do thing d with *it
}
Run Code Online (Sandbox Code Playgroud)
我发现 b) 更好读,因为 a) 会变得笨重,非常容易且难以理解。但是 a) 我认为会跑得更快。那么哪一个是更好的风格呢?myContainer 将包含多达 10.000 个元素,并且必须重复此过程,因此性能很重要。
将单独的任务拆分为不同的循环还有进一步的重构优势。
在处理大数据集时,循环性能并不总是很直接,因此您通常应该从可读性开始,并在需要时返回到单循环。
这是Martin Fowler的Split Loop 重构示例。
您经常会看到循环同时做两种不同的事情,因为它们可以通过一次循环来完成。事实上,大多数程序员会对这种重构感到非常不舒服,因为它迫使你执行两次循环——这是双倍的工作。
但是像许多优化一样,在一个循环中做两件不同的事情比单独做更不清晰。它还会给进一步重构带来问题,因为它引入了阻碍进一步重构的临时变量。因此,在重构时,不要害怕摆脱循环。优化时,如果循环很慢,则会出现这种情况,此时将循环重新组合在一起是正确的。您可能会惊讶于循环不是瓶颈的频率,或者后来的重构如何开启另一个更强大的优化。
void printValues() {
double averageAge = 0;
double totalSalary = 0;
for (int i = 0; i < people.length; i++) {
averageAge += people[i].age;
totalSalary += people[i].salary;
}
averageAge = averageAge / people.length;
System.out.println(averageAge);
System.out.println(totalSalary);
}
Run Code Online (Sandbox Code Playgroud)
void printValues() {
double totalSalary = 0;
for (int i = 0; i < people.length; i++) {
totalSalary += people[i].salary;
}
double averageAge = 0;
for (int i = 0; i < people.length; i++) {
averageAge += people[i].age;
}
averageAge = averageAge / people.length;
System.out.println(averageAge);
System.out.println(totalSalary);
}
Run Code Online (Sandbox Code Playgroud)
void printValues() {
System.out.println(averageAge());
System.out.println(totalSalary());
}
private double averageAge() {
double result = 0;
for (int i = 0; i < people.length; i++) {
result += people[i].age;
}
return result / people.length;
}
private double totalSalary() {
double result = 0;
for (int i = 0; i < people.length; i++) {
result += people[i].salary;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)