[英]Array traversal in F#
在 F# 中迭代數組的最快方法是什么? 使用 Array.[index] 似乎創建(通過查看發布模式下的程序集生成)調用 asm 指令。 有沒有辦法避免這種情況? 謝謝
120: me.[i] <- me.[i] ||| you.[i]
0000005b 8B 45 F8 mov eax,dword ptr [ebp-8]
0000005e 8B 55 E0 mov edx,dword ptr [ebp-20h]
00000061 3B 42 04 cmp eax,dword ptr [edx+4]
00000064 72 05 jb 0000006B
00000066 E8 35 CD B9 65 call 65B9CDA0
0000006b 8B 4C C2 08 mov ecx,dword ptr [edx+eax*8+8]
0000006f 8B 5C C2 0C mov ebx,dword ptr [edx+eax*8+0Ch]
00000073 8B 45 F8 mov eax,dword ptr [ebp-8]
00000076 8B 55 DC mov edx,dword ptr [ebp-24h]
00000079 3B 42 04 cmp eax,dword ptr [edx+4]
0000007c 72 05 jb 00000083
0000007e E8 1D CD B9 65 call 65B9CDA0
00000083 0B 4C C2 08 or ecx,dword ptr [edx+eax*8+8]
00000087 0B 5C C2 0C or ebx,dword ptr [edx+eax*8+0Ch]
0000008b 89 4D EC mov dword ptr [ebp-14h],ecx
0000008e 89 5D F0 mov dword ptr [ebp-10h],ebx
00000091 8B 45 F8 mov eax,dword ptr [ebp-8]
00000094 8B 55 E0 mov edx,dword ptr [ebp-20h]
00000097 3B 42 04 cmp eax,dword ptr [edx+4]
0000009a 72 05 jb 000000A1
0000009c E8 FF CC B9 65 call 65B9CDA0
000000a1 8B 4D EC mov ecx,dword ptr [ebp-14h]
000000a4 8B 5D F0 mov ebx,dword ptr [ebp-10h]
000000a7 89 4C C2 08 mov dword ptr [edx+eax*8+8],ecx
000000ab 89 5C C2 0C mov dword ptr [edx+eax*8+0Ch],ebx
更新:使用 Array.iter 給我:
122: me |> Array.iteri (fun i elem -> me.[i] <- me.[i] ||| you.[i] )
0000003a B9 18 26 70 00 mov ecx,702618h
0000003f E8 7C 53 A5 FF call FFA553C0
00000044 89 45 E0 mov dword ptr [ebp-20h],eax
00000047 FF 75 E4 push dword ptr [ebp-1Ch]
0000004a 8B 55 E8 mov edx,dword ptr [ebp-18h]
0000004d 8B 4D E0 mov ecx,dword ptr [ebp-20h]
00000050 FF 15 00 26 70 00 call dword ptr ds:[00702600h]
00000056 8B 55 E8 mov edx,dword ptr [ebp-18h]
00000059 8B 4D E0 mov ecx,dword ptr [ebp-20h]
0000005c 8B 05 DC 27 70 00 mov eax,dword ptr ds:[007027DCh]
00000062 6A 00 push 0
00000064 6A 00 push 0
00000066 6A 01 push 1
00000068 50 push eax
00000069 83 3D 88 A2 63 66 00 cmp dword ptr ds:[6663A288h],0
00000070 74 09 je 0000007B
00000072 51 push ecx
00000073 52 push edx
00000074 E8 C2 DE C1 65 call 65C1DF3B
00000079 5A pop edx
0000007a 59 pop ecx
0000007b E8 A7 5C 96 65 call 65965D27
00000080 CC int 3
作為猜測,您在調試器下運行時獲得了反匯編的源代碼。 調試器的存在阻止了許多 JIT 優化。 作為演示:
let assign (a : _[]) (b : _[]) =
for i = 0 to a.Length do
a.[i] <- b.[i]
System.Diagnostics.Trace.Assert(false)
|> ignore
assign [|1|] [|0|]
使用調試器發布:
a.[i] <- b.[i]
0000003b mov eax,dword ptr [ebp-8]
0000003e mov edx,dword ptr [ebp-14h]
00000041 cmp eax,dword ptr [edx+4]
00000044 jb 0000004B
00000046 call 762798A8
0000004b mov eax,dword ptr [edx+eax*4+8]
0000004f mov dword ptr [ebp-0Ch],eax
00000052 mov eax,dword ptr [ebp-8]
00000055 mov edx,dword ptr [ebp-10h]
00000058 cmp eax,dword ptr [edx+4]
0000005b jb 00000062
0000005d call 762798A8
00000062 mov ecx,dword ptr [ebp-0Ch]
00000065 mov dword ptr [edx+eax*4+8],ecx
....
釋放,沒有調試器(使用 ctrl+f5 運行,當 Assert window 彈出時按重試,然后才將調試器附加到進程)
a.[i] <- b.[i]
00000017 cmp esi,dword ptr [ebx+4]
0000001a jae 00000043
0000001c mov eax,dword ptr [ebx+esi*4+8]
00000020 cmp esi,dword ptr [edi+4]
00000023 jae 00000043
00000025 mov dword ptr [edi+esi*4+8],eax
....
你試過Array.iter
嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.