Pattern matching in F # is much slower than If else / switch in C #?

Possible duplicate:
F # seems slower than other languages ​​... what can I do to speed it up?

I'm a little curious about how pattern matching works, so I did the following test:

poolEven contains 10,000 elements 0,1,2,3, (2500 equals)

testSize = 100000

IfelseEven(100000)takes 650 ms (the switch will be faster, but I don’t attach the code), but it MatchEven(100000)takes 7000 ms, which is 10 times

Does performance impairment relate to Array.Fold? I am 100% sure that if I go behind IEnumerable.Aggregate, the speed will decrease significantly. But I thought that F # handled Array.Foldbetter than C # cIEnumerable.Aggregate . I want to compare the performance of most common (equivalent) methods of coding in two languages, but not hard to make them identical.

Tests are performed in x64 version, with 10+ studies conducted on average with proper warm-up

WITH#:

public void IfelseEven(int testSize)
{
    Ifelse(testSize, poolEven);
}

void Ifelse(int testSize, int[] pool)
{
    long sum = 0;
    for (int i = 0; i < testSize; i++)
    {
        for (int j = 0; j < poolCapacity;j++ )
        {
            var item = pool[j];
            if (item == 0)
            {
                sum += 5;
            }
            else if (item == 1)
            {
                sum += 1;
            }
            else if (item == 2)
            {
                sum += 2;
            }
            else if (item == 3)
            {
                sum += 3;
            }
            else
            {
                sum += 4;
            }
        }
    }
}

public void MatchEven(int testSize)
{
    PatternMatch.myMatch(testSize, poolEven);
}

F #:

module PatternMatch

let mat acc elem =
    acc +
    match elem with
    | 0 -> 5L
    | 1 -> 1L
    | 2 -> 2L
    | 3 -> 3L
    | _ -> 4L

let sum (pool:int[])=
    Array.fold mat 0L pool;

let myMatch testSize pool=
    let mutable tmp = 0L
    for i=0 to testSize do
        tmp <- sum(pool) + tmp
    tmp
+5
source share
2 answers

- . , , . . F #, :

let ifElse testSize (pool: _[]) = 
  let mutable sum = 0L
  for i = 0 to testSize - 1 do
    for j = 0 to pool.Length - 1 do
      match pool.[j] with
      | 0 -> sum <- sum + 5L
      | 1 -> sum <- sum + 1L
      | 2 -> sum <- sum + 2L
      | 3 -> sum <- sum + 3L
      | _ -> sum <- sum + 4L
  sum

# ( ):

# 5655
F # 4003

, leppie . , 78% Array.fold - .

+11

, , match vs if/elseif . fold vs recurse - .

(, , ), . Release build,.NET 4.5, x64 target arch.

  • # F # if\elseif ( ).

  • F # match , if\elseif ( )

  • # switch ( ).

+7

All Articles