【发布时间】:2020-05-08 19:04:28
【问题描述】:
我目前正在对 F# 映射与 C# 字典进行一些测试。我意识到它们在实现方面完全不同,但它们确实为各自的语言提供了相同的用途。
我设计了一个简单的测试来检查插入时间,因为 F# 映射是不可变的,因此它必须为每次插入创建一个全新的映射。我想知道这有多大的成功。
测试如下:
//F#
module Test =
let testMapInsert () =
let sw = Stopwatch()
let rec fillMap endIdx curr map =
if curr = endIdx then
map
else
fillMap endIdx (curr + 1) (map |> Map.add curr curr)
sw.Start ()
let q = fillMap 100000000 Map.empty
sw.Stop ()
printfn "%A" sw.ElapsedMilliseconds
//C#
class Program
{
static void Test(int x) {
var d = new Dictionary<int,int>();
for (int i = 0; i < x; i++) {
d.Add(i,i);
}
}
static void Main(string[] args) {
Stopwatch sw = new Stopwatch();
sw.Start();
Test(10000000);
sw.Stop();
System.Console.WriteLine(sw.ElapsedMilliseconds);
//FSHARP.Test.testMapInsert(); f# function called in c#.
}
}
使用它进行 1000 万次元素插入会产生以下以 ms 为单位的时间:
C#: 332
F#: 13605
我认为 C# 字典会快一些,但差别很大。
有没有办法为这种用例加快 F# 字典的速度?或者这就是这种情况,F# 映射在这些情况下为了线程安全而与性能进行权衡?
【问题讨论】:
-
Just F# Map 是一种基于红/黑树的不可变数据结构,与 C# 中基于哈希表的可变字典相比。人们确实希望这会产生一些性能差异,但根据我的经验,F# Map 的最大差异来自于缓慢的通用比较函数。它很慢,因为它是通用的。我正在试验一个允许自定义通用比较函数的地图实现,但它的效果还不够好,无法对 F# 核心进行 PR。
标签: c# .net dictionary f#