- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我把一个Ocaml程序转成F#,整体性能和Ocaml一样。
但是,为了达到这一点,我尝试用 Option 值替换异常。
该程序对具有 int*int*int
的列表、 map 等很有效。 (=三元组 ints
)。
我有一个我不明白的性能泄漏。谁能解释我怎么做
在一个名为的函数内有 90% 的总执行时间
System.Tuple`3.System.Collections.IStructuralEquatable.Equals(
object, class System.Collections.IEqualityComparer)
最佳答案
正如人们所指出的那样,没有代码很难诊断问题,但我会尽我所能:-)
你的问题让我运行了一个我计划运行一段时间的测试,这是为了测试作为关联容器键的引用类型与值类型的性能。我的假设是基于对 .net 运行时的模糊感觉,对于较小的键大小(您的 3 个整数),值类型会胜出。我似乎错了([编辑]实际上进一步的测试证明它是正确的![/编辑])
让我们看一些代码(按照惯例,微性能测试,所以请谨慎对待):
我使用了 5 个不同风格的不同容器来存储整数(F# 足以为结构类型和记录创建相等性和比较器):
type KeyStruct(_1':int, _2':int, _3':int) = struct
member this._1 = _1'
member this._2 = _2'
member this._3 = _3'
end
type KeyGenericStruct<'a>(_1':'a, _2':'a, _3':'a) = struct
member this._1 = _1'
member this._2 = _2'
member this._3 = _3'
end
type KeyRecord = { _1 : int; _2 : int; _3 : int }
type KeyGenericRecord<'a> = { _1 : 'a; _2 : 'a; _3 : 'a }
let inline RunTest<'a when 'a : equality> iterationCount createAssociativeMap (createKey:_->_->_->'a) =
System.GC.Collect ()
System.GC.WaitForFullGCComplete () |> ignore
let data = [|
for a in 0..99 do
for b in 0..99 do
for c in 0..99 do
yield a,b,c |]
// shuffle
let r = System.Random (0)
for i = 0 to data.Length-1 do
let j = r.Next (i, data.Length)
let t = data.[i]
data.[i] <- data.[j]
data.[j] <- t
let keyValues =
data
|> Array.mapi (fun i k -> k, 0.5-(float i)/(float data.Length))
|> Array.toSeq
let sw = System.Diagnostics.Stopwatch.StartNew ()
let mapper = createAssociativeMap createKey keyValues
let creationTime = sw.ElapsedMilliseconds
let sw = System.Diagnostics.Stopwatch.StartNew ()
let mutable checksum = 0.
for i = 0 to iterationCount do
let a, b, c = r.Next 100, r.Next 100, r.Next 100
let key = createKey a b c
checksum <- checksum + (mapper key)
let accessTime= sw.ElapsedMilliseconds
printfn "checksum %f elapsed %d/%d (%s)" checksum creationTime accessTime (typeof<'a>.Name)
let RunNTrials<'a when 'a : equality> = RunTest<'a> 1000000
let createDictionary create keyValues =
let d = System.Collections.Generic.Dictionary<_,_> ()
keyValues
|> Seq.map (fun ((_1,_2,_3),value) -> create _1 _2 _3, value)
|> Seq.iter (fun (key,value) -> d.[key] <- value)
(fun key -> d.[key])
let createDict create keyValues =
let d =
keyValues
|> Seq.map (fun ((_1,_2,_3),value) -> create _1 _2 _3, value)
|> dict
(fun key -> d.[key])
let createMap create keyValues =
let d =
keyValues
|> Seq.map (fun ((_1,_2,_3),value) -> create _1 _2 _3, value)
|> Map.ofSeq
(fun key -> d.[key])
let createCustomArray create keyValues =
let maxA = 1 + (keyValues |> Seq.map (fun ((a,_,_),_) -> a) |> Seq.max)
let maxB = 1 + (keyValues |> Seq.map (fun ((_,b,_),_) -> b) |> Seq.max)
let maxC = 1 + (keyValues |> Seq.map (fun ((_,_,c),_) -> c) |> Seq.max)
let createIndex a b c = a * maxB * maxC + b * maxC + c
let values : array<float> = Array.create (maxA * maxB * maxC) 0.
keyValues
|> Seq.iter (fun ((a,b,c),d) -> values.[createIndex a b c] <- d)
(fun (a,b,c) -> values.[a * maxB * maxC + b * maxC + c])
let RunDictionary<'a when 'a : equality> = RunNTrials<'a> createDictionary
let RunDict<'a when 'a : equality> = RunNTrials<'a> createDict
let RunMap<'a when 'a : comparison> = RunNTrials<'a> createMap
let RunCustomArray = RunNTrials<_> createCustomArray
printfn "Using .net's System.Collections.Generic.Dictionary"
RunDictionary (fun a b c -> { KeyRecord._1=a; _2=b; _3=c })
RunDictionary (fun a b c -> { KeyGenericRecord._1=a; _2=b; _3=c })
RunDictionary (fun a b c -> KeyStruct(a, b, c))
RunDictionary (fun a b c -> KeyGenericStruct(a, b, c))
RunDictionary (fun a b c -> (a, b, c))
printfn "Using f# 'dict'"
RunDict (fun a b c -> { KeyRecord._1=a; _2=b; _3=c })
RunDict (fun a b c -> { KeyGenericRecord._1=a; _2=b; _3=c })
RunDict (fun a b c -> KeyStruct(a, b, c))
RunDict (fun a b c -> KeyGenericStruct(a, b, c))
RunDict (fun a b c -> (a, b, c))
printfn "Using f# 'Map'"
RunMap (fun a b c -> { KeyRecord._1=a; _2=b; _3=c })
RunMap (fun a b c -> { KeyGenericRecord._1=a; _2=b; _3=c })
RunMap (fun a b c -> KeyStruct(a, b, c))
RunMap (fun a b c -> KeyGenericStruct(a, b, c))
RunMap (fun a b c -> (a, b, c))
printfn "Using custom array"
RunCustomArray (fun a b c -> (a, b, c))
Using .net's System.Collections.Generic.Dictionary
checksum -55.339450 elapsed 874/562 (KeyRecord)
checksum -55.339450 elapsed 1251/898 (KeyGenericRecord`1)
checksum -55.339450 elapsed 569/1024 (KeyStruct)
checksum -55.339450 elapsed 740/1427 (KeyGenericStruct`1)
checksum -55.339450 elapsed 2497/2218 (Tuple`3)
Using f# 'dict'
checksum -55.339450 elapsed 979/628 (KeyRecord)
checksum -55.339450 elapsed 1614/1206 (KeyGenericRecord`1)
checksum -55.339450 elapsed 3237/5625 (KeyStruct)
checksum -55.339450 elapsed 3290/5626 (KeyGenericStruct`1)
checksum -55.339450 elapsed 2448/1914 (Tuple`3)
Using f# 'Map'
checksum -55.339450 elapsed 8453/2638 (KeyRecord)
checksum -55.339450 elapsed 31301/25441 (KeyGenericRecord`1)
checksum -55.339450 elapsed 30956/26931 (KeyStruct)
checksum -55.339450 elapsed 53699/49274 (KeyGenericStruct`1)
checksum -55.339450 elapsed 32203/25274 (Tuple`3)
Using custom array
checksum -55.339450 elapsed 484/160 (Tuple`3)
关于performance - F# 处理复杂键(如数据结构中的 int*int*int)比 Ocaml 慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16557761/
我正在尝试使用 y 组合器在 Scala 中定义 gcd: object Main { def y[A,B]( f : (A => B) => A => B ) : A => B = f(y(f)
我正在尝试了解返回指向函数的指针的函数,在我尝试编译代码后,它给了我这种错误: cannot convert int (*(int))(int) to int (*(int))(int) in ass
所以我一直在关注 youtube 上的游戏编程教程,然后弹出了这段代码:bufferedImageObject.getRGB(int, int, int, int, int[], int, int);
我正在将时间现在 与存储在数据库某处的时间进行比较。数据库中存储的时间格式为“yyyyMMddHHmmss”。例如,数据库可能会为存储的时间值返回 201106203354。然后我使用一个函数将时间现
例如 Maze0.bmp (0,0) (319,239) 65 120 Maze0.bmp (0,0) (319,239) 65 120 (254,243,90) Maze0.bmp (0,0) (
评论 Steve Yegge的post关于 server-side Javascript开始讨论语言中类型系统的优点和这个 comment描述: ... examples from H-M style
我正在研究 C 的指针,从 Deitel 的书中我不明白 int(*function)(int,int) 和 int*function(int, int) 表示函数时。 最佳答案 C 中读取类型的经验
您好,我使用 weblogic 11g 创建 war 应用程序,我对 joda time 的方法有疑问 new DateTime(int, int, int, int, int, int); 这抛出了
Create a method called average that calculates the average of the numbers passed as parameters. The
var a11: Int = 0 var a12: Int = 0 var a21: Int = 0 var a22: Int = 0 var valueDeterminant = a11 * a12
我正在为一个项目设置 LED 阵列。我得到了一个 LED 阵列,可以根据引脚变化电压进行更改,但我无法添加更多引脚。 当我尝试时,编译失败并显示错误:函数“int getMode(int, int,
除了创建对列表执行简单操作的函数之外,我对 haskell 还是很陌生。我想创建一个列表,其中包含 Int 类型的内容, 和 Int -> Int -> Int 类型的函数. 这是我尝试过的: dat
这个问题已经有答案了: Java add buttons dynamically as an array [duplicate] (4 个回答) 已关闭 7 年前。 StackOverFlow问题今天
我有几个 EditText View ,我想在其中设置左侧的图像,而 setCompoundDrawablesWithIntrinsicBounds 似乎不起作用。图形似乎没有改变。 有人知道为什么会
#include using namespace std; int main() { static_assert(is_constructible, int(*)(int,int)>::val
fun sum(a: Int, b: Int) = a + b val x = 1.to(2) 我在找: sum.tupled(x),或者 sum(*x) 当然,以上都不能用 Kotlin 1.1.3
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
type foo = A of int * int | B of (int * int) int * int 和 (int * int) 有什么区别?我看到的唯一区别在于模式匹配: let test_
我正在尝试制作一个 slider 游戏。在这个类中,我使用 Graphics 对象 g2 的 drawImage 方法来显示“拼图”的 block 。但在绘制类方法中,我收到此错误:找不到符号方法dr
我试着理解这个表达: static Func isOdd = i => (i & 1) == 1; 但是这是什么意思呢? 例如我有 i = 3。然后 (3 & 1) == 1 或 i = 4。然后
我是一名优秀的程序员,十分优秀!