Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory 了解F#内存消耗_Memory_F# - Fatal编程技术网

Memory 了解F#内存消耗

Memory 了解F#内存消耗,memory,f#,Memory,F#,我最近一直在玩弄F#并在下面写了这个小片段,它只是创建了一些随机的3d向量,将它们放入一个列表,将每个向量映射到它的长度,并将所有这些值相加 运行该程序(作为一个Release Build.exe,不是交互式的),二进制文件在这种特殊情况下(10百万个向量)消耗大约550MB的RAM。一个Vec3对象应该占12个字节(或者16个字节,假设发生了一些对齐)。即使你用32个字节粗略计算一些簿记开销(每个对象的字节数*10兆)/1024/1024),你仍然比实际消耗量少200兆。天真地说,我假设最终每

我最近一直在玩弄F#并在下面写了这个小片段,它只是创建了一些随机的3d向量,将它们放入一个列表,将每个向量映射到它的长度,并将所有这些值相加

运行该程序(作为一个Release Build.exe,不是交互式的),二进制文件在这种特殊情况下(10百万个向量)消耗大约550MB的RAM。一个Vec3对象应该占12个字节(或者16个字节,假设发生了一些对齐)。即使你用32个字节粗略计算一些簿记开销(每个对象的字节数*10兆)/1024/1024),你仍然比实际消耗量少200兆。天真地说,我假设最终每个单体有10百万*4字节,因为Vec3对象是“映射的”

到目前为止,我的猜测是:要么我把我的列表的一个(或多个)副本保存在某个地方,而我并不知道,要么一些中间结果从未被垃圾收集?我无法想象从System.Object继承会带来这么多开销。 有人能给我指出正确的方向吗

短暂性脑缺血发作

类型Vec3(x:single,y:single,z:single)=
设mag=sqrt(x*x+y*y+z*z)
成员自身。大小=mag
重写self.ToString()=sprintf“[%f%f%f]”x y z
多少钱=10000000
设可变rng=System.Random()
设sw=new System.Diagnostics.Stopwatch()
sw.Start()
随机向量=
让可变结果=[]
对于x=1到len do
设可变累加器=[]
对于i=1到3,请执行以下操作
累计(x级)
[]
让主argv=
printfn“你好,世界”
设res=sum_len_func(映射到mag_func(随机向量(多少)))
printfn“处理%i个项目花费了%i,结果是%f”多少(sw.elapsedmillyses)res
System.Console.ReadKey()|>忽略
0//返回整数退出代码

首先,您的vec是ref类型而不是值类型(不是结构)。因此,在12个字节(12+16)的顶部放置一个指针。然后列表是一个单链表,因此另一个16字节用于.net引用。然后,您的list.map将创建一个中间列表。

首先
sizeof
返回8(这似乎是合理的),因此确实会有很多开销-这就是垃圾收集程序的问题(就像.net上的所有程序一样)-真的很难测量reals的内存占用(顺便问一下:您是如何测量的?这只是来自任务管理器的值还是您询问了一些内存分析器?)只要看一看,你就会产生大量的临时
accum
列表和其他东西,因此,如果有相当多的物体飞来飞去,要由地面军事中心处置,这应该不会太令人惊讶。我刚才在任务管理器中查看了总消耗量的值。我现在尝试使用VS2013的内存分析器,Vector类本身显示为每个12字节(正如预期的那样),但主块似乎已被列表本身用完。这可能是丹尼尔·费边所指的问题。尽管如此,为什么列表在我将其折叠为一个值后仍然存在?只是做了一个快速内存分析(使用100而不是10mio)-最后将有100个Vec3(使用3200字节)和502个列表(使用16.064字节)-但也有187个字符串(使用4.722字节),一些对象,…-但是你会看到列表受到了重创(只有100个em来自地图,其余的是你在random_vec_iter中的可变部分),GC会随时抓取列表;)
type Vec3(x: single, y: single, z:single) = 

    let mag = sqrt(x*x + y*y + z*z)

    member self.Magnitude = mag

    override self.ToString() = sprintf "[%f %f %f]" x y z

let how_much = 10000000

let mutable rng = System.Random()

let sw = new System.Diagnostics.Stopwatch()
sw.Start()

let random_vec_iter len =

    let mutable result = []

    for x = 1 to len do
        let mutable accum = []

        for i = 1 to 3 do
            accum <- single(rng.NextDouble())::accum
        result <- Vec3(accum.[0], accum.[1], accum.[2])::result
    result

sum_len_func = List.reduce (fun x y -> x+y)
let map_to_mag_func = List.map (fun (x:Vec3) -> x.Magnitude)

[<EntryPoint>]
let main argv = 
    printfn "Hello, World"
    let res = sum_len_func (map_to_mag_func (random_vec_iter(how_much)))
    printfn "doing stuff with %i items took %i, result is %f" how_much     (sw.ElapsedMilliseconds) res
    System.Console.ReadKey() |> ignore
    0 // return an integer exit code