简体   繁体   中英

Array traversal in F#

What is the fastest way of iterating over an array in F#? Using Array.[index] seems to create (by looking at the assembly produce in Release mode) call asm instruction. Is there a way to avoid this? Thanks

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  

Update: using Array.iter give me:

   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 

As a guess, you've obtained disassembled source while running under the debugger. Presence of debugger prevents a number of JIT optimizations. As a demonstration:

let assign (a : _[]) (b : _[]) =
    for i = 0 to a.Length do
        a.[i] <- b.[i] 
        System.Diagnostics.Trace.Assert(false)
        |> ignore

assign [|1|] [|0|]

Release, with debugger:

        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 
....

Release, without debugger (use ctrl+f5 for run, press Retry when Assert window pops up and only then attach debugger to process)

        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 
....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM