在 for 循环中高效地打印每 x 次迭代
Efficiently print every x iterations in for loop
我正在编写一个程序,其中某个 for 循环被迭代了很多次。
单次迭代不会花费很长时间,但由于程序如此频繁地迭代循环,因此需要相当长的时间来计算。
为了在不减慢程序速度的情况下获得有关程序进度的更多信息,我想每第 x 步打印一次进度。
是否有不同的方法来执行此操作,而不是像这样使用模数的条件:
for(int i = 0; i < some_large_number; i++){
if(i % x == 0)
printf("%f%%\r", percent);
//some other code
.
.
.
}
?
先谢谢了
我会这样做:
int j = x;
for (int i = 0; i < some_large_number; i++){
if(--j == 0) {
printf("%f%%\r", percent);
j = x;
}
//some other code
.
.
.
}
关于您的性能问题的最快方法是使用嵌套循环:
unsigned int x = 6;
unsigned int segments = some_large_number / x;
unsigned int y;
for ( unsigned int i = 0; i < segments; i++ ) {
printf("%f%%\r", percent);
for ( unsigned int j = 0; j < x; j++ ) {
/* some code here */
}
}
// If some_large_number can´t be divided evenly through `x`:
if (( y = (some_large_number % x)) != 0 )
{
for ( unsigned int i = 0; i < y; i++ ) {
/* same code as inside of the former inner loop. */
}
}
另一个示例是使用不同的计数变量进行检查,通过将其与 x - 1
进行比较来执行打印过程,如果匹配则将变量重置为 -1
:
unsigned int x = 6;
unsigned int some_large_number = 100000000;
for ( unsigned int i = 0, int j = 0; i < some_large_number; i++, j++ ) {
if(j == (x - 1))
{
printf("%f%%\r", percent);
j = -1;
}
/* some code here */
}
将 some_large_number 除以 x。现在循环 x 次并将其与新整数嵌套,然后打印百分比。我的意思是:
int temp = some_large_number/x;
for (int i = 0; i < x; i++){
for (int j = 0; j < temp; j++){
//some code
}
printf("%f%%\r", percent);
}
此代码:
for(int i = 0; i < some_large_number; i++){
if(i % x == 0)
printf("%f%%\r", percent);
//some other code
.
.
.
}
可以重组为:
/* Partition the execution into blocks of x iterations, possibly including a
final fragmentary block. The expression (some_large_number+(x-1))/x
calculates some_large_number/x with any fraction rounded up.
*/
for (int block = 0, i = 0; block < (some_large_number+(x-1))/x; ++block)
{
printf("%f%%\r", percent);
// Set limit to the lesser of the end of the current block or some_large_number.
int limit = (block+1) * x;
if (some_large_number < limit) limit = some_large_number;
// Iterate the original code.
for (; i < limit; ++i)
{
//some other code
}
}
具有以下注意事项和属性:
- 内部循环没有比原始循环更多的工作(它没有额外的变量来计算或测试)并且完全删除了
i % x == 0
测试。这对于内部循环来说是最佳的,因为它尽可能减少了名义上的工作量,尽管现实世界的硬件有时会有挑剔的行为,可能导致更多的计算时间而实际工作更少。
- 引入了新标识符
block
和 limit
,但可以进行更改以避免与原始代码中的使用发生任何冲突。
- 除上述之外,内部循环的操作与原始代码相同:它以与原始代码相同的顺序看到相同的
i
值,因此该代码无需更改。
some_large_number+(x-1)
可能会溢出 int
。
我正在编写一个程序,其中某个 for 循环被迭代了很多次。
单次迭代不会花费很长时间,但由于程序如此频繁地迭代循环,因此需要相当长的时间来计算。
为了在不减慢程序速度的情况下获得有关程序进度的更多信息,我想每第 x 步打印一次进度。
是否有不同的方法来执行此操作,而不是像这样使用模数的条件:
for(int i = 0; i < some_large_number; i++){
if(i % x == 0)
printf("%f%%\r", percent);
//some other code
.
.
.
}
?
先谢谢了
我会这样做:
int j = x;
for (int i = 0; i < some_large_number; i++){
if(--j == 0) {
printf("%f%%\r", percent);
j = x;
}
//some other code
.
.
.
}
关于您的性能问题的最快方法是使用嵌套循环:
unsigned int x = 6;
unsigned int segments = some_large_number / x;
unsigned int y;
for ( unsigned int i = 0; i < segments; i++ ) {
printf("%f%%\r", percent);
for ( unsigned int j = 0; j < x; j++ ) {
/* some code here */
}
}
// If some_large_number can´t be divided evenly through `x`:
if (( y = (some_large_number % x)) != 0 )
{
for ( unsigned int i = 0; i < y; i++ ) {
/* same code as inside of the former inner loop. */
}
}
另一个示例是使用不同的计数变量进行检查,通过将其与 x - 1
进行比较来执行打印过程,如果匹配则将变量重置为 -1
:
unsigned int x = 6;
unsigned int some_large_number = 100000000;
for ( unsigned int i = 0, int j = 0; i < some_large_number; i++, j++ ) {
if(j == (x - 1))
{
printf("%f%%\r", percent);
j = -1;
}
/* some code here */
}
将 some_large_number 除以 x。现在循环 x 次并将其与新整数嵌套,然后打印百分比。我的意思是:
int temp = some_large_number/x;
for (int i = 0; i < x; i++){
for (int j = 0; j < temp; j++){
//some code
}
printf("%f%%\r", percent);
}
此代码:
for(int i = 0; i < some_large_number; i++){
if(i % x == 0)
printf("%f%%\r", percent);
//some other code
.
.
.
}
可以重组为:
/* Partition the execution into blocks of x iterations, possibly including a
final fragmentary block. The expression (some_large_number+(x-1))/x
calculates some_large_number/x with any fraction rounded up.
*/
for (int block = 0, i = 0; block < (some_large_number+(x-1))/x; ++block)
{
printf("%f%%\r", percent);
// Set limit to the lesser of the end of the current block or some_large_number.
int limit = (block+1) * x;
if (some_large_number < limit) limit = some_large_number;
// Iterate the original code.
for (; i < limit; ++i)
{
//some other code
}
}
具有以下注意事项和属性:
- 内部循环没有比原始循环更多的工作(它没有额外的变量来计算或测试)并且完全删除了
i % x == 0
测试。这对于内部循环来说是最佳的,因为它尽可能减少了名义上的工作量,尽管现实世界的硬件有时会有挑剔的行为,可能导致更多的计算时间而实际工作更少。 - 引入了新标识符
block
和limit
,但可以进行更改以避免与原始代码中的使用发生任何冲突。 - 除上述之外,内部循环的操作与原始代码相同:它以与原始代码相同的顺序看到相同的
i
值,因此该代码无需更改。 some_large_number+(x-1)
可能会溢出int
。