Array.Count() much slower than List.Count()

前端 未结 4 1871
梦如初夏
梦如初夏 2021-02-01 18:00

When using the extension method of IEnumerable Count(), an array is at least two times slower than a list.

Function                      Co         


        
4条回答
  •  臣服心动
    2021-02-01 18:30

    32-bit profiling analysis (all in ms, only interesting bits, JIT inlining disabled):

    Name    Count   'Inc Time'  'Ex Time'   'Avg Inc Time'  'Avg Ex Time'
    System.Linq.Enumerable::Count():int32    
            20000000    13338.38    7830.49 0.0007  0.0004
    System.SZArrayHelper::get_Count():int32   
            10000000    4063.9      2651.44 0.0004  0.0003
    System.Collections.Generic.List::get_Count():int32    
            10000000    1443.99     1443.99 0.0001  0.0001
    System.Runtime.CompilerServices.JitHelpers::UnsafeCast(Object):System.__Canon   
            10000004    1412.46     1412.46 0.0001  0.0001
    

    System.SZArrayHelper::get_Count() seems to call System.Runtime.CompilerServices.JitHelpers::UnsafeCast for the array case.

    For the list, List.Count simply returns the size.

    Inc time is cost including child calls. Ex time is cost of method body only.

    When inlining is disabled, the Array.Count() is twice as slow.

    It could be due to the fact mentioned the now deleted answer. It would appear the attributes applied (ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success) and SecuritySafeCritical) prevents the runtime from inlining the call, hence the big difference (38 times slower in my case in 32-bit mode).

    To profile this yourself:

    Get https://github.com/leppie/IronScheme/raw/master/IronScheme/tools/IronScheme.Profiler.x86.dll Run the app (x86 build only) as:

    regsvr32 IronScheme.Profiler.x86.dll
    set COR_PROFILER={9E2B38F2-7355-4C61-A54F-434B7AC266C0}
    set COR_ENABLE_PROFILING=1
    ConsoleApp1.exe
    

    When app exits, a report.tab file is created which can then be used in Excel.

提交回复
热议问题