这个问题已经在这里有了答案:
已关闭8年。
我对模式匹配的性能有点好奇,因此我进行了以下测试:poolEven
包含10000个元素,分别为0、1、2、3(等于2500)testSize = 100000
IfelseEven(100000)
需要650毫秒(切换会更快,但我没有附加代码),而MatchEven(100000)
则需要7000毫秒,即10倍的时间
性能下降是否来自Array.Fold
?我100%确信,如果我使用IEnumerable.Aggregate
,速度将大大降低。 但我认为F#使用Array.Fold
比C#处理IEnumerable.Aggregate
更好。我想比较两种语言最常见的(等效)编码方式的性能,而不是使它们相同的严格方式。
测试是在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
顺便说一句,嬉皮士在评论中把它钉了钉子。我分析了您的代码,而78%的时间都花在了
Array.fold
上—在紧密循环中不好用。关于c# - F#中的模式匹配要慢得多,否则要在C#中切换? [复制],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12182291/