我是否正确使用 Deedle Series.map?
Am I using Deedle Series.map correctly?
在对不同的集合进行了一些测试之后,我想看看哪个表现最好。
我测试了一个数组、seq、列表和一系列在 0.0 和 1.0 之间均匀随机选择的 1,000,000 个点。然后我在 sigmoid 函数上应用它们各自的 .map 函数:
let sigmoid x = 1. / (1. + exp(-x))
然后我使用 BenchmarkDotNet 计算平均执行时间,我得到了我认为 "ugly" 用于 Deedle.Series 的时间。在我看来,Deedle 确实"map" 不友好。我做事正确吗?
// * Summary *
BenchmarkDotNet=v0.11.5, OS=Windows 7 SP1 (6.1.7601.0)
Intel Xeon CPU E5-1620 v3 3.50GHz, 1 CPU, 8 logical and 4 physical cores
Frequency=3410126 Hz, Resolution=293.2443 ns, Timer=TSC
.NET Core SDK=3.0.100-preview5-011568
[Host] : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT DEBUG [AttachedDebugger]
DefaultJob : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------- |------------:|-----------:|-----------:|-----------:|----------:|----------:|----------:|
| Array | 21.29 ms | 0.4217 ms | 0.9255 ms | 406.2500 | 406.2500 | 406.2500 | 15.26 MB |
| List | 173.52 ms | 2.9243 ms | 2.7354 ms | 11250.0000 | 4500.0000 | 1500.0000 | 61.04 MB |
| Seq | 127.90 ms | 2.5884 ms | 7.4267 ms | 36600.0000 | - | - | 183.11 MB |
| Series | 1,751.04 ms | 37.6797 ms | 59.7640 ms | 99000.0000 | 6000.0000 | 6000.0000 | 603.31 MB |
我认为您的测量值很可能是正确的。 Deedle 系列无疑在数组上增加了显着的开销——这是因为它还在处理缺失值方面添加了许多额外功能,以及与系列是 key-value 映射这一事实相关的所有功能。
如果您正在进行不涉及混乱数据或带索引的数据的纯数值计算,那么您可能应该使用矩阵处理库或原始数组。
我使用 #time
进行的简单测量如下:
#time
let rnd = System.Random()
let s = series [ for i in 0 .. 1000000 -> i, rnd.NextDouble() ]
let a = [| for i in 0 .. 1000000 -> rnd.NextDouble() |]
// ~950ms
let r = 1. / (1. + exp(-s))
// ~290ms
s |> Series.map (fun _ v -> 1. / (1. + exp(-v)))
// ~25ms
a |> Array.map (fun v -> 1. / (1. + exp(-v)))
值得注意的是,Series.map
比直接做一系列二元运算符要快得多,因为它只需要创建一个新的系列实例。
在对不同的集合进行了一些测试之后,我想看看哪个表现最好。 我测试了一个数组、seq、列表和一系列在 0.0 和 1.0 之间均匀随机选择的 1,000,000 个点。然后我在 sigmoid 函数上应用它们各自的 .map 函数:
let sigmoid x = 1. / (1. + exp(-x))
然后我使用 BenchmarkDotNet 计算平均执行时间,我得到了我认为 "ugly" 用于 Deedle.Series 的时间。在我看来,Deedle 确实"map" 不友好。我做事正确吗?
// * Summary *
BenchmarkDotNet=v0.11.5, OS=Windows 7 SP1 (6.1.7601.0)
Intel Xeon CPU E5-1620 v3 3.50GHz, 1 CPU, 8 logical and 4 physical cores
Frequency=3410126 Hz, Resolution=293.2443 ns, Timer=TSC
.NET Core SDK=3.0.100-preview5-011568
[Host] : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT DEBUG [AttachedDebugger]
DefaultJob : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------- |------------:|-----------:|-----------:|-----------:|----------:|----------:|----------:|
| Array | 21.29 ms | 0.4217 ms | 0.9255 ms | 406.2500 | 406.2500 | 406.2500 | 15.26 MB |
| List | 173.52 ms | 2.9243 ms | 2.7354 ms | 11250.0000 | 4500.0000 | 1500.0000 | 61.04 MB |
| Seq | 127.90 ms | 2.5884 ms | 7.4267 ms | 36600.0000 | - | - | 183.11 MB |
| Series | 1,751.04 ms | 37.6797 ms | 59.7640 ms | 99000.0000 | 6000.0000 | 6000.0000 | 603.31 MB |
我认为您的测量值很可能是正确的。 Deedle 系列无疑在数组上增加了显着的开销——这是因为它还在处理缺失值方面添加了许多额外功能,以及与系列是 key-value 映射这一事实相关的所有功能。
如果您正在进行不涉及混乱数据或带索引的数据的纯数值计算,那么您可能应该使用矩阵处理库或原始数组。
我使用 #time
进行的简单测量如下:
#time
let rnd = System.Random()
let s = series [ for i in 0 .. 1000000 -> i, rnd.NextDouble() ]
let a = [| for i in 0 .. 1000000 -> rnd.NextDouble() |]
// ~950ms
let r = 1. / (1. + exp(-s))
// ~290ms
s |> Series.map (fun _ v -> 1. / (1. + exp(-v)))
// ~25ms
a |> Array.map (fun v -> 1. / (1. + exp(-v)))
值得注意的是,Series.map
比直接做一系列二元运算符要快得多,因为它只需要创建一个新的系列实例。