在 Haxe 中循环最有效的方法是什么?
What is the most efficient way to loop in Haxe?
我找不到任何关于 Haxe 中循环之间实际性能差异的信息。他们提到 Vector 有一些速度优化,因为它是固定长度的。遍历对象的最佳方法是什么?它是否取决于可迭代对象(例如 Array vs. Vector vs. Map)?
为什么 Haxe 在 SO 上的存在这么少?其他所有语言都对这个问题回答了 5 次以上...
由于没有人做过我发现的性能基准测试,我决定 运行 进行测试,以便未来的 Haxe 程序员可以使用此信息。
首先请注意:如果您不经常 运行 循环,它会非常快,对性能几乎没有影响。所以如果只使用数组更容易,那就去做吧。只有当你 运行 一遍又一遍地检查这个东西 and/or 如果它真的很大,性能才会受到影响。
事实证明,您的最佳选择主要取决于您的数据结构。我发现当您执行 for each 样式循环而不是标准的 for 循环或 while 循环时,数组往往会更快。在小尺寸情况下,数组本质上与向量一样快,因此在大多数情况下您无需担心使用哪一个。但是,如果您正在处理相当大的数组,那么切换到 Vector 将非常有益。如果您使用 Vector,则使用标准的 for 或 while 循环本质上是等效的(尽管 while 更快)。地图也非常快,特别是如果你避免 foreach 循环。
为了得出这些结论,我首先在这些条件下测试了循环:
- 测试数组、向量和地图(地图只是为了好玩)。
- 将每一个填充为
structure[i] = i
,其中 i 在 0...size 中,尺寸在 [20, 100, 1000, 10000, 100000] 中,因此您可以找到适合您的尺寸。
- 使用三种 for 循环类型测试了每个大小的每个数据结构
for (i in 0...size)
for (item in array)
while (i < size)
在每个循环中,我执行了查找和赋值 arr[i] = arr[i] + 1;
- 每个循环类型都在其自己的循环内
for (iter in 0...1000)
以更准确地了解循环的执行方式。请注意,我只是将每个循环的时间加在一起,我没有平均或类似的东西。因此,如果一个数组需要 12 秒,那么平均执行一次实际上是 12 / 1000 => 0.012 秒。
最后,这是我的基准测试(运行 在 HaxeDevelop 的 neko 调试中):
Running test on size 20:
for (i...20) x 1000
Array : 0.0019989013671875
Vector : 0
Map : 0.00300025939941406
for each(i in iterable) x 1000
Array : 0.00100135803222656
Vector : 0.00099945068359375
Map : 0.0209999084472656
while (i < 20) x 1000
Array : 0.00200080871582031
Vector : 0.00099945068359375
Map : 0.0019989013671875
Running test on size 100:
for (i...100) x 1000
Array : 0.0120010375976563
Vector : 0.0019989013671875
Map : 0.0120010375976563
for each(i in iterable) x 1000
Array : 0.00600051879882813
Vector : 0.00299835205078125
Map : 0.0190010070800781
while (i < 100) x 1000
Array : 0.0119991302490234
Vector : 0.00200080871582031
Map : 0.0119991302490234
Running test on size 1000:
for (i...1000) x 1000
Array : 0.11400032043457
Vector : 0.0179996490478516
Map : 0.104999542236328
for each(i in iterable) x 1000
Array : 0.0550003051757813
Vector : 0.0229988098144531
Map : 0.210000991821289
while (i < 1000) x 1000
Array : 0.105998992919922
Vector : 0.0170001983642578
Map : 0.101999282836914
Running test on size 10000:
for (i...10000) x 1000
Array : 1.09500122070313
Vector : 0.180000305175781
Map : 1.09700012207031
for each(i in iterable) x 1000
Array : 0.553998947143555
Vector : 0.222999572753906
Map : 2.17600059509277
while (i < 10000) x 1000
Array : 1.07900047302246
Vector : 0.170999526977539
Map : 1.0620002746582
Running test on size 100000:
for (i...100000) x 1000
Array : 10.9670009613037
Vector : 1.80499839782715
Map : 11.0330009460449
for each(i in iterable) x 1000
Array : 5.54100036621094
Vector : 2.21299934387207
Map : 20.4000015258789
while (i < 100000) x 1000
Array : 10.7889995574951
Vector : 1.71500015258789
Map : 10.8209991455078
total time: 83.8239994049072
希望对担心性能和 Haxe 以及需要使用大量循环的人有所帮助。
我找不到任何关于 Haxe 中循环之间实际性能差异的信息。他们提到 Vector 有一些速度优化,因为它是固定长度的。遍历对象的最佳方法是什么?它是否取决于可迭代对象(例如 Array vs. Vector vs. Map)?
为什么 Haxe 在 SO 上的存在这么少?其他所有语言都对这个问题回答了 5 次以上...
由于没有人做过我发现的性能基准测试,我决定 运行 进行测试,以便未来的 Haxe 程序员可以使用此信息。
首先请注意:如果您不经常 运行 循环,它会非常快,对性能几乎没有影响。所以如果只使用数组更容易,那就去做吧。只有当你 运行 一遍又一遍地检查这个东西 and/or 如果它真的很大,性能才会受到影响。
事实证明,您的最佳选择主要取决于您的数据结构。我发现当您执行 for each 样式循环而不是标准的 for 循环或 while 循环时,数组往往会更快。在小尺寸情况下,数组本质上与向量一样快,因此在大多数情况下您无需担心使用哪一个。但是,如果您正在处理相当大的数组,那么切换到 Vector 将非常有益。如果您使用 Vector,则使用标准的 for 或 while 循环本质上是等效的(尽管 while 更快)。地图也非常快,特别是如果你避免 foreach 循环。
为了得出这些结论,我首先在这些条件下测试了循环:
- 测试数组、向量和地图(地图只是为了好玩)。
- 将每一个填充为
structure[i] = i
,其中 i 在 0...size 中,尺寸在 [20, 100, 1000, 10000, 100000] 中,因此您可以找到适合您的尺寸。 - 使用三种 for 循环类型测试了每个大小的每个数据结构
在每个循环中,我执行了查找和赋值for (i in 0...size) for (item in array) while (i < size)
arr[i] = arr[i] + 1;
- 每个循环类型都在其自己的循环内
for (iter in 0...1000)
以更准确地了解循环的执行方式。请注意,我只是将每个循环的时间加在一起,我没有平均或类似的东西。因此,如果一个数组需要 12 秒,那么平均执行一次实际上是 12 / 1000 => 0.012 秒。
最后,这是我的基准测试(运行 在 HaxeDevelop 的 neko 调试中):
Running test on size 20:
for (i...20) x 1000
Array : 0.0019989013671875
Vector : 0
Map : 0.00300025939941406
for each(i in iterable) x 1000
Array : 0.00100135803222656
Vector : 0.00099945068359375
Map : 0.0209999084472656
while (i < 20) x 1000
Array : 0.00200080871582031
Vector : 0.00099945068359375
Map : 0.0019989013671875
Running test on size 100:
for (i...100) x 1000
Array : 0.0120010375976563
Vector : 0.0019989013671875
Map : 0.0120010375976563
for each(i in iterable) x 1000
Array : 0.00600051879882813
Vector : 0.00299835205078125
Map : 0.0190010070800781
while (i < 100) x 1000
Array : 0.0119991302490234
Vector : 0.00200080871582031
Map : 0.0119991302490234
Running test on size 1000:
for (i...1000) x 1000
Array : 0.11400032043457
Vector : 0.0179996490478516
Map : 0.104999542236328
for each(i in iterable) x 1000
Array : 0.0550003051757813
Vector : 0.0229988098144531
Map : 0.210000991821289
while (i < 1000) x 1000
Array : 0.105998992919922
Vector : 0.0170001983642578
Map : 0.101999282836914
Running test on size 10000:
for (i...10000) x 1000
Array : 1.09500122070313
Vector : 0.180000305175781
Map : 1.09700012207031
for each(i in iterable) x 1000
Array : 0.553998947143555
Vector : 0.222999572753906
Map : 2.17600059509277
while (i < 10000) x 1000
Array : 1.07900047302246
Vector : 0.170999526977539
Map : 1.0620002746582
Running test on size 100000:
for (i...100000) x 1000
Array : 10.9670009613037
Vector : 1.80499839782715
Map : 11.0330009460449
for each(i in iterable) x 1000
Array : 5.54100036621094
Vector : 2.21299934387207
Map : 20.4000015258789
while (i < 100000) x 1000
Array : 10.7889995574951
Vector : 1.71500015258789
Map : 10.8209991455078
total time: 83.8239994049072
希望对担心性能和 Haxe 以及需要使用大量循环的人有所帮助。