Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 令人惊讶的嵌套循环持续时间_Excel_Vba - Fatal编程技术网

Excel 令人惊讶的嵌套循环持续时间

Excel 令人惊讶的嵌套循环持续时间,excel,vba,Excel,Vba,我的VBA代码中有一个内部循环和外部循环。我认为总的执行时间可以估计为外循环计数*内循环计数,但情况似乎并非如此,因为执行10*10^8操作大约需要5秒,但执行10^8*10操作大约需要24秒。与多次重复内部循环相比,多次重复外部循环似乎使总执行时间更长,尽管两个示例中的操作总数保持不变。它应该这样工作吗?为什么呢?我做错什么了吗 Sub test() Dim i As Long Dim j As Long Dim t As Single maxI = 0 '1 maxJ = 9 '1 bil

我的VBA代码中有一个内部循环和外部循环。我认为总的执行时间可以估计为外循环计数*内循环计数,但情况似乎并非如此,因为执行10*10^8操作大约需要5秒,但执行10^8*10操作大约需要24秒。与多次重复内部循环相比,多次重复外部循环似乎使总执行时间更长,尽管两个示例中的操作总数保持不变。它应该这样工作吗?为什么呢?我做错什么了吗

Sub test()
Dim i As Long
Dim j As Long
Dim t As Single

maxI = 0 '1
maxJ = 9 '1 bilion

Do While maxJ >= 0

    t = Timer
    For i = 1 To 10 ^ maxI
    For j = 1 To 10 ^ maxJ
    Next j
    Next i

    Debug.Print maxI + maxJ & " " & maxI & " " & maxJ & " " & Timer - t

    maxI = maxI + 1
    maxJ = maxJ - 1
Loop

End Sub
结果数据集以外部循环中的双线性重复和内部循环中的一个重复开始,如下所示:

+-------------------+-----------------+-----------------+----------+
| total_operations  | outer_loop_cnt  | inner_loop_cnt  |   time   |
+-------------------+-----------------+-----------------+----------+
|                9  |              9  |              0  | 222,2305 |
|                9  |              8  |              1  | 24,52734 |
|                9  |              7  |              2  | 8,300781 |
|                9  |              6  |              3  | 5,683594 |
|                9  |              5  |              4  | 5,070313 |
|                9  |              4  |              5  | 5,109375 |
|                9  |              3  |              6  | 5,167969 |
|                9  |              2  |              7  | 4,933594 |
|                9  |              1  |              8  | 4,898438 |
|                9  |              0  |              9  | 5,109375 |
+-------------------+-----------------+-----------------+----------+
+---+---+---+----------+
| 9 | 0 | 9 | 4,800781 |
| 9 | 1 | 8 | 4,890625 |
| 9 | 2 | 7 | 4,808594 |
| 9 | 3 | 6 | 4,800781 |
| 9 | 4 | 5 | 4,757813 |
| 9 | 5 | 4 | 4,972656 |
| 9 | 6 | 3 | 5,308594 |
| 9 | 7 | 2 | 6,980469 |
| 9 | 8 | 1 | 24,54297 |
| 9 | 9 | 0 | 222,3828 |
+---+---+---+----------+
Do While maxJ >= 0

    upper_i = 10 ^ maxI
    upper_j = 10 ^ maxJ
    t = Timer
    For i = 1 To upper_i
    For j = 1 To upper_j
    ...
结果数据集以内部循环中的bilion重复和外部循环中的一个重复开始,如下所示:

+-------------------+-----------------+-----------------+----------+
| total_operations  | outer_loop_cnt  | inner_loop_cnt  |   time   |
+-------------------+-----------------+-----------------+----------+
|                9  |              9  |              0  | 222,2305 |
|                9  |              8  |              1  | 24,52734 |
|                9  |              7  |              2  | 8,300781 |
|                9  |              6  |              3  | 5,683594 |
|                9  |              5  |              4  | 5,070313 |
|                9  |              4  |              5  | 5,109375 |
|                9  |              3  |              6  | 5,167969 |
|                9  |              2  |              7  | 4,933594 |
|                9  |              1  |              8  | 4,898438 |
|                9  |              0  |              9  | 5,109375 |
+-------------------+-----------------+-----------------+----------+
+---+---+---+----------+
| 9 | 0 | 9 | 4,800781 |
| 9 | 1 | 8 | 4,890625 |
| 9 | 2 | 7 | 4,808594 |
| 9 | 3 | 6 | 4,800781 |
| 9 | 4 | 5 | 4,757813 |
| 9 | 5 | 4 | 4,972656 |
| 9 | 6 | 3 | 5,308594 |
| 9 | 7 | 2 | 6,980469 |
| 9 | 8 | 1 | 24,54297 |
| 9 | 9 | 0 | 222,3828 |
+---+---+---+----------+
Do While maxJ >= 0

    upper_i = 10 ^ maxI
    upper_j = 10 ^ maxJ
    t = Timer
    For i = 1 To upper_i
    For j = 1 To upper_j
    ...
更新:如果我修改代码,使上界不会像下面这样计算每个循环:

+-------------------+-----------------+-----------------+----------+
| total_operations  | outer_loop_cnt  | inner_loop_cnt  |   time   |
+-------------------+-----------------+-----------------+----------+
|                9  |              9  |              0  | 222,2305 |
|                9  |              8  |              1  | 24,52734 |
|                9  |              7  |              2  | 8,300781 |
|                9  |              6  |              3  | 5,683594 |
|                9  |              5  |              4  | 5,070313 |
|                9  |              4  |              5  | 5,109375 |
|                9  |              3  |              6  | 5,167969 |
|                9  |              2  |              7  | 4,933594 |
|                9  |              1  |              8  | 4,898438 |
|                9  |              0  |              9  | 5,109375 |
+-------------------+-----------------+-----------------+----------+
+---+---+---+----------+
| 9 | 0 | 9 | 4,800781 |
| 9 | 1 | 8 | 4,890625 |
| 9 | 2 | 7 | 4,808594 |
| 9 | 3 | 6 | 4,800781 |
| 9 | 4 | 5 | 4,757813 |
| 9 | 5 | 4 | 4,972656 |
| 9 | 6 | 3 | 5,308594 |
| 9 | 7 | 2 | 6,980469 |
| 9 | 8 | 1 | 24,54297 |
| 9 | 9 | 0 | 222,3828 |
+---+---+---+----------+
Do While maxJ >= 0

    upper_i = 10 ^ maxI
    upper_j = 10 ^ maxJ
    t = Timer
    For i = 1 To upper_i
    For j = 1 To upper_j
    ...
对于更大的外部循环,我得到了更好的结果。但似乎这仍然是事实,最好是内外循环运行次数几乎相等,以获得最佳性能。对我来说,这仍然令人惊讶。有什么想法吗

9 9 0 60,07031
9 8 1 14,8125
9 7 2 10,36719
9 6 3 9,414063
9 5 4 9,507813
9 4 5 9,40625
9 3 6 9,523438
9 2 7 9,835938
9 1 8 12,875
9 0 9 11,02344

9 0 9 9,75
9 1 8 9,257813
9 2 7 9,265625
9 3 6 9,273438
9 4 5 9,1875
9 5 4 9,164063
9 6 3 9,21875
9 7 2 10,42969
9 8 1 14,96094
9 9 0 59,66406

顺便说一句,如何设置表格格式?

是的,这很有意义
For
循环边界始终在循环开始时计算。因此,如果你运行内循环十亿次,你要计算
10^maxI
一次,然后
10^maxJ
一次,然后是
j=j+1的十亿次重复。
如果运行外循环十亿次,你要计算
10^maxI
一次,和
10^maxJ
j=j+1
10亿次。

这也是我的解释。在如此高的重复次数下,计算会变得昂贵。检查是否存在这种情况的一个好方法是预先计算10^Max并将其设置为for循环值。哪些数据类型是
maxI
maxJ
upper\u i
,以及
upper\u j
?它们都是Long吗?我已经显式地将所有这些属性输入为Long,但这并没有显著的区别。