c# - F# 中的模式匹配比 C# 中的 If else/switch 慢得多吗?

标签 c# performance f# pattern-matching

<分区>

Possible Duplicate:
F# seems slower than other languages… what can I do to speed it up?

我对模式匹配的性能有点好奇,所以做了如下测试:

poolEven 包含 0,1,2,3 的 10000 个元素,(2500 等于)

testSize = 100000

IfelseEven(100000) 需要 650 毫秒(切换会更快,但我没有附上代码)而 MatchEven(100000) 需要 7000 毫秒,这是 10 倍的时间

性能下降是否来自 Array.Fold?我 100% 确定,如果我选择 IEnumerable.Aggregate,速度会大大降低。 但我认为 F# 处理 Array.Fold 的效果优于使用 IEnumerable.Aggregate 的 C#。我想比较两种语言中最常见(等效)编码方式的性能,而不是使它们相同的严格方式。

测试是在 x64 版本中完成的,10 次以上的试验在适当的预热下取平均值

C#:

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

最佳答案

投票结束——我们可以整天玩这个游戏。有关为什么不同代码可能具有不同执行时间的更多评论,请参阅 this question and 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

根据我的测量,这轻而易举地舔了 C# 函数(而且它仍然更短且更具可读性):

C# 5655
F#4003

顺便说一下,leppie 在评论中指出了这一点。我分析了您的代码,发现 78% 的时间花在了 Array.fold 上——在紧密循环中不好。

关于c# - F# 中的模式匹配比 C# 中的 If else/switch 慢得多吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12182291/

相关文章:

C# 为这个程序添加自定义 Windows 上下文菜单

python - 降低 python 中的浮点精度以提高性能

c# - 先学什么?

c# - 在 C# 中检查 double 是否为整数的好方法是什么?

c# - 使用 Jira SOAP API 的 PasswordEncoderNotFoundException

sql-server - 对连接到网络存储设备的数据库进行负载测试

f# - 无法在 F# 中创建 ZipArchive

list - 从列表 F# 中删除每第 3 个元素

c# - Objective-C 等效于 C# 只读变量

c++ - 几何变换