如何缩短这个迭代问题的运行时间 我有C++的片段,下面迭代1-50,打印出一个语句,而不是数字,如果元素可以被2或3整除。当前运行时间约为1.47秒。如何优化此问题以更快地运行 #include <iostream> int main() { for (int j = 1; j <= 50; j++) { if (j % 2 == 0 && j % 3 == 0) { std::cout << "Both" << std::endl; } else if (j % 2 == 0) { std::cout << "Two" << std::endl; } else if (j % 3 == 0) { std::cout << "Three" << std::endl; } else { std::cout << j << std::endl; } } }
您可以将循环内的endl更改为\n,然后std::cout您可以将循环内的endl更改为\n,然后std::cout我几乎不相信它在任何i7上都那么慢。应该最多运行几毫秒 然而,问题是“如何改进”,为此有几点: 打开优化-O2 删除循环中的std::cout。而是创建一个例如std::string,将输出附加到循环中的该变量,然后在循环之后输出它。仅测量回路,而不是std::cout 使用嵌套循环,如@MichaelDorgan。如何缩短这个迭代问题的运行时间 我有C++的片段,下面迭代1-50,打印出一个语句,而不是数字,如果元素可以被2或3整除。当前运行时间约为1.47秒。如何优化此问题以更快地运行 #include <iostream> int main() { for (int j = 1; j <= 50; j++) { if (j % 2 == 0 && j % 3 == 0) { std::cout << "Both" << std::endl; } else if (j % 2 == 0) { std::cout << "Two" << std::endl; } else if (j % 3 == 0) { std::cout << "Three" << std::endl; } else { std::cout << j << std::endl; } } },c++,C++,您可以将循环内的endl更改为\n,然后std::cout您可以将循环内的endl更改为\n,然后std::cout我几乎不相信它在任何i7上都那么慢。应该最多运行几毫秒 然而,问题是“如何改进”,为此有几点: 打开优化-O2 删除循环中的std::cout。而是创建一个例如std::string,将输出附加到循环中的该变量,然后在循环之后输出它。仅测量回路,而不是std::cout 使用嵌套循环,如@MichaelDorgan。 我几乎不相信它在任何i7上都会那么慢。应该最多运行几毫秒 然而,
我几乎不相信它在任何i7上都会那么慢。应该最多运行几毫秒 然而,问题是“如何改进”,为此有几点: 打开优化-O2 删除循环中的std::cout。而是创建一个例如std::string,将输出附加到循环中的该变量,然后在循环之后输出它。仅测量回路,而不是std::cout 使用嵌套循环,如@MichaelDorgan。
只有50次迭代?将它展开成一个状态机50个状态,1个开关语句,没有数学运算。或者,将其转换为预计算值的单个打印。仍然无法回答为什么程序运行速度如此之慢…只有50次迭代?将它展开成一个状态机50个状态,1个开关语句,没有数学运算。或者,将其转换为预计算值的单个打印。仍然无法回答为什么程序运行如此之慢…首先,在您真正需要它之前,不要尝试优化struff,记住这一点。我真的不相信代码需要1.4秒才能运行。但是好的 我能看到的唯一一件事是,您可以做得更好,那就是在编译时进行分组。这样,您就不会计算每个数字的模,您只需查看是否需要打印文本 因此,我所做的是创建一个在编译时求值的函数,如果需要,它返回一个带有文本的const char*,如果不需要,则返回带有nullprt的const char*:
constexpr const char *type(int n) {
if (n % 2 == 0 && n % 3 == 0) {
return "Both";
}
if (n % 2 == 0) {
return "Two";
}
if (n % 3 == 0) {
return "Three";
}
return nullptr;
}
接下来,我有一个包含所有所需结果的数组:
const int max_number = 50;
constexpr const static std::array<const char *, max_number + 1> results{
type(0),
type(1),
type(2),
type(3),
type(4),
type(5),
type(6),
type(7),
type(8),
type(9),
type(10),
type(11),
type(12),
type(13),
type(14),
type(15),
type(16),
type(17),
type(18),
type(19),
type(20),
type(21),
type(22),
type(23),
type(24),
type(25),
type(26),
type(27),
type(28),
type(29),
type(30),
type(31),
type(32),
type(33),
type(34),
type(35),
type(36),
type(37),
type(38),
type(39),
type(40),
type(41),
type(42),
type(43),
type(44),
type(45),
type(46),
type(47),
type(48),
type(49),
type(50)
};
最后,在运行时,您只需检查它是否为null:
int main() {
Timer t{};
for (int j = 1; j <= max_number; j++) {
if (results[j]) {
cout << results[j] << '\n';
} else {
cout << j << '\n';
}
}
}
结果:
在我的机器中,最初的方法花费了0.05到0.08毫秒。
新方法耗时0.04至0.07毫秒。
所以是的,它更快。但这么快,它将改变一切
现在我真的想弄清楚这一点。在需要之前不要进行优化!。下面是一个例子,它们都是用-O3编译的。差别非常小,代码更大、更复杂。选择简单的方法首先,在你真正需要它之前不要尝试优化struff,记住这一点。我真的不相信代码需要1.4秒才能运行。但是好的
我能看到的唯一一件事是,您可以做得更好,那就是在编译时进行分组。这样,您就不会计算每个数字的模,您只需查看是否需要打印文本
因此,我所做的是创建一个在编译时求值的函数,如果需要,它返回一个带有文本的const char*,如果不需要,则返回带有nullprt的const char*:
constexpr const char *type(int n) {
if (n % 2 == 0 && n % 3 == 0) {
return "Both";
}
if (n % 2 == 0) {
return "Two";
}
if (n % 3 == 0) {
return "Three";
}
return nullptr;
}
接下来,我有一个包含所有所需结果的数组:
const int max_number = 50;
constexpr const static std::array<const char *, max_number + 1> results{
type(0),
type(1),
type(2),
type(3),
type(4),
type(5),
type(6),
type(7),
type(8),
type(9),
type(10),
type(11),
type(12),
type(13),
type(14),
type(15),
type(16),
type(17),
type(18),
type(19),
type(20),
type(21),
type(22),
type(23),
type(24),
type(25),
type(26),
type(27),
type(28),
type(29),
type(30),
type(31),
type(32),
type(33),
type(34),
type(35),
type(36),
type(37),
type(38),
type(39),
type(40),
type(41),
type(42),
type(43),
type(44),
type(45),
type(46),
type(47),
type(48),
type(49),
type(50)
};
最后,在运行时,您只需检查它是否为null:
int main() {
Timer t{};
for (int j = 1; j <= max_number; j++) {
if (results[j]) {
cout << results[j] << '\n';
} else {
cout << j << '\n';
}
}
}
结果:
在我的机器中,最初的方法花费了0.05到0.08毫秒。
新方法耗时0.04至0.07毫秒。
所以是的,它更快。但这么快,它将改变一切
现在我真的想弄清楚这一点。在需要之前不要进行优化!。下面是一个例子,它们都是用-O3编译的。差别非常小,代码更大、更复杂。喜欢简单的方式在我的机器上运行相同的代码需要12-66毫秒。我认为问题在于你的时间计量。您可以使用C++的标准工具(如chrono library)测量运行时:
此代码将以毫秒为单位测量实际循环的持续时间,并将其打印出来。它将忽略程序启动、初始化和停止的任何开销,并让您了解实际的代码性能,而不是操作系统的进程运行性能。我打赌它会显示速度的极大提高,对我来说,它会打印总运行时间:4ms。最后。在我的机器上运行同样的代码需要12-66毫秒。我认为问题在于你的时间计量。您可以使用C++的标准工具(如chrono library)测量运行时: 此代码将以毫秒为单位测量实际循环的持续时间,并将其打印出来。它将忽略程序启动、初始化和停止的任何开销,并让您了解实际的代码性能,而不是操作系统的进程运行性能
曼斯。我打赌它会显示速度的极大提高,对我来说,它会打印总运行时间:4ms。最后。您确定是指编译时,而不是运行时吗?不管怎样,这两种方法都只需要不到一眨眼的时间。1.4秒的简单计算和50张打印?你的电脑是仓鼠供电的吗?运行一个32gb内存和1080。。。也许我在vs代码上使用的扩展正在抛出错误的运行时,您可以尝试停止使用endl。真的很慢@巴布洛切斯,那是一个货物崇拜的神秘主义者。对于任何体面的现代终端实现或CPU来说,差异可能只有几毫秒甚至纳秒。你确定你指的是编译时,而不是运行时吗?不管怎样,这两种方法都只需要不到一眨眼的时间。1.4秒的简单计算和50张打印?你的电脑是仓鼠供电的吗?运行一个32gb内存和1080。。。也许我在vs代码上使用的扩展正在抛出错误的运行时,您可以尝试停止使用endl。真的很慢@巴布洛切斯,那是一个货物崇拜的神秘主义者。对于任何体面的现代终端实现或CPU来说,差异可能只有几毫秒甚至纳秒。而且,由于I/O几乎总是速度减慢的根源,我相信这一点。但是我仍然不相信它最初运行的时间是1.4秒…@MichaeldOrganger:好吧,如果输出通过管道传输到某种自动测试框架,比如expect工具,那么1.4秒是挂钟时间,而不仅仅是他的程序所花费的时间。我打赌他的报告工具会给他微秒或其他时间。或者他有10个反病毒程序,他的系统是完全拥有的…@Farnsworth:我不希望添加flush来加快速度,它只是恢复您通过删除endl而丢失的行为。我正在使用vs code btwAnd的coderunner扩展,因为I/O几乎总是导致速度减慢的原因,我相信这一点。但是我仍然不相信它最初运行的时间是1.4秒…@MichaeldOrganger:好吧,如果输出通过管道传输到某种自动测试框架,比如expect工具,那么1.4秒是挂钟时间,而不仅仅是他的程序所花费的时间。我打赌他的报告工具会给他微秒或其他时间。或者他有10个反病毒程序,他的系统是完全拥有的…@Farnsworth:我不希望添加flush来加快速度,这只是通过去掉endl来恢复您丢失的行为。我使用的是vs code BTW的coderunner扩展,只测量我认为无法解决原始问题的循环,因为它测量的是不同的I/O时间量。尽管包括I/O,但仍有其他事情在发生。顺便说一句,在-O2,编译器可能会隐藏与不嵌套循环相关的任何内容,这也是因为数学非常简单。我认为仅测量循环会使原始问题失败,因为它测量的是不同的I/O时间量。即使包括I/O,也会发生其他事情。顺便说一句,在-O2,编译器可能会隐藏与不嵌套循环相关的任何内容-再次因为数学很简单。我开始认为这可能与我使用的vs扩展有关…我开始认为这可能与我使用的vs扩展有关…好的,谢谢。问题似乎是我用来编译的VS代码扩展。它输出的运行时不准确。问题是关于优化。这是我唯一想到的事情。祝您的扩展好运,希望您能让它工作得足够有趣-展开循环并预计算值。是的,这是更快的,因为它是值得的:好的,谢谢你。问题似乎是我用来编译的VS代码扩展。它输出的运行时不准确。问题是关于优化。这是我唯一想到的事情。祝您的扩展好运,希望您能让它工作得足够有趣-展开循环并预计算值。是的,它的价值更快: