- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有大量(数百万/数十亿+)这些简单的 Foo
数据结构:
data Foo = Foo
{ a :: {-# UNPACK #-}!Int
, b :: Int
}
由于存在如此多的此类内容,因此有必要考虑它们消耗了多少内存。
在 64 位机器上,每个 Int
为 8 个字节,因此 a
只需要 8 个字节(因为它是严格且未打包的)。但是b
会占用多少内存呢?我想这会根据 thunk 是否被评估而改变,对吧?
我想在一般情况下这是不可能判断的,因为 b
可能依赖于任意数量的内存位置,这些位置仅保留在内存中,以防 b
需要进行评估。但是,如果 b
仅依赖于(一些非常昂贵的操作)a
呢?那么,是否有一种确定性的方法来判断将使用多少内存?
最佳答案
除了 user239558 的回答之外,为了回应您的评论,我还想指出一些工具,可以让您检查值的堆表示,自己找到此类问题的答案并查看效果优化和不同的编译方式。
告诉你闭包的大小。在这里,您可以看到(在 64 位计算机上)在评估形式和垃圾回收之后,Foo 1 2
本身需要 24 个字节,包括依赖项在内,总共需要 40 个字节:
Prelude GHC.DataSize Test> let x = Foo 1 2Prelude GHC.DataSize Test> xFoo {a = 1, b = 2}Prelude GHC.DataSize Test> System.Mem.performGCPrelude GHC.DataSize Test> closureSize x24Prelude GHC.DataSize Test> recursiveSize x40
To reproduce this you need to load the data definition in compiled form with -O
, otherwise, the {-# UNPACK #-}
pragma has no effect.
Now let us create a thunk and see that the size goes up considerably:
Prelude GHC.DataSize Test> let thunk = 2 + 3::IntPrelude GHC.DataSize Test> let x = Foo 1 thunkPrelude GHC.DataSize Test> x `seq` return ()Prelude GHC.DataSize Test> System.Mem.performGCPrelude GHC.DataSize Test> closureSize x24Prelude GHC.DataSize Test> recursiveSize x400
Now this is quite excessive. The reason is that this calculation includes references to static closures, Num
typeclass dictionaries and the like, and generally the GHCi bytecode is very unoptimized. So let’s put that in a proper Haskell program. Running
main = do
l <- getArgs
let n = length l
n `seq` return ()
let thunk = trace "I am evaluated" $ n + n
let x = Foo 1 thunk
a x `seq` return ()
performGC
s1 <- closureSize x
s2 <- closureSize thunk
r <- recursiveSize x
print (s1, s2, r)
给出(24, 24, 48)
,所以现在Foo
值由Foo
本身和一个thunk组成。为什么只有 thunk,不应该还有对 n
添加另外 16 个字节的引用吗?为了回答这个问题,我们需要一个更好的工具:
这个库(由我创建)可以调查堆并准确地告诉您数据在那里的表示方式。因此,将这一行添加到上面的文件中:
buildHeapTree 1000 (asBox x) >>= putStrLn . ppHeapTree
we get (when we pass five parameters to the program) the result Foo (_thunk 5) 1
. Note that the order of arguments is swapped on the heap, because pointers always come before data. The plain 5
indicates that the closure of the thunk stores its argument unboxed.
As a last exercise we verify this by making the thunk lazy in n
: Now
main = do
l <- getArgs
let n = length l
n `seq` return ()
let thunk = trace "I am evaluated" $ n
let x = Foo 1 thunk
a x `seq` return ()
performGC
s1 <- closureSize x
s2 <- closureSize thunk
s3 <- closureSize n
r <- recursiveSize x
buildHeapTree 1000 (asBox x) >>= putStrLn . ppHeapTree
print (s1, s2, s3, r)
给出 Foo (_thunk (I# 4)) 1
的堆表示,并带有 n
的单独闭包(如 I 的存在所示) #
构造函数)并显示值的预期大小及其总数,(24,24,16,64)
。
哦,如果这仍然太高,getClosureRaw为您提供原始字节。
关于haskell - thunk 使用多少内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13982863/
谁能给我解释一下 Thunk 是什么? 还有一个 ATL Thunk? 我知道 thunk 与 vtbl 和执行代码有关,以找到正确的函数指针。我说得对吗? 最佳答案 它是一段从根本上改变执行环境的适
我创建了这个小程序,它创建了一个长时间运行的 thunk,最终因异常而失败。然后,多个线程尝试对其进行评估。 import Control.Monad import Control.Concurren
我正在尝试输入检查我的 redux-thunk使用 Typescript 编写代码。 来自 Redux 的官方文档:Usage with Redux Thunk ,我们得到这个例子: // src/t
我正在尝试围绕“async/await”思考,async 函数总是返回 Promises 并将异步函数与 Redux Thunks 结合使用这一事实 -- 我知道 async 函数根据定义总是返回一个
这个问题与过去不同,这就是为什么。这个问题是什么时候。由于两者本身都是很好的框架,所以问题是我什么时候应该使用 thunk 而不是 saga。因为我的一位 friend 一直坚持让我在我们的应用程序中
我正在更新我的项目中的依赖项(redux 4.0.1、redux-thunk 2.3.0、typescript 3.1.3),我很难在我的两个项目中找到 redux-thunk 的正确类型 Actio
这个问题在这里已经有了答案: Create grouping variable for consecutive sequences and split vector (5 个答案) 关闭 9 个月前
我有以下两个 Redux 操作(thunk) export const getA = () => async (dispatch, getState) => { const response =
我正在尝试编写在 makeThunk 函数内部编写的代码,但在这里我无法理解如何在内部传递 cb 的值makethunk 函数。 我想在使用回调调用 thunk 后记录总和值! 我的代码看起来像这样:
假设我有大量(数百万/数十亿+)这些简单的 Foo 数据结构: data Foo = Foo { a :: {-# UNPACK #-}!Int , b :: Int } 由于
这个问题是关于虚函数调用的(可能的)实现(我相信它被 gcc 使用)。 考虑以下场景: F 类继承自 D 类(可能还有其他类),而 D 类继承自 B 类(并非虚拟)。 D重写了B中声明的虚方法f();
我想定义一个重载方法,一个接受 function0,一个接受 function1,即: def produces(f: Context => Any): Processor = ... def pro
我有一个应用程序可以在渲染时获取一些用户信息。因此,当应用程序首次启动时,它会使用 getUserInformation() 函数获取数据。用户无需手动登录,应用在公司内网。 export funct
我以为我知道什么是闭包,但我不太确定是否阅读了一些有关 React 的文章。 下面的函数是“thunk”吗?(对我来说这是一个闭包,我从一篇关于 React https://spin.atomicob
我已经看到它用于编程(特别是在 C++ 领域),但不知道它是什么。大概这是一种设计模式,但我可能是错的。谁能举一个thunk的好例子吗? 最佳答案 thunk通常指一小段代码,作为函数调用,做一些小事
我有以下操作 export function getAllBooks() { return function(dispatch) { return axios.get('http://l
什么是与 EXE 文件中用于导入外部 DLL 中使用的函数的导入地址表相关的 thunk 表? 这个 thunk 表只是一个包含“Thunk”到其他函数的表吗? 最佳答案 Thunks 是 导入表的一
我不明白为什么 Action 创建者被调用但卡在中间的某个地方。我的组件 import React, { Component } from 'react'; import { connect } fr
问题: 我使用redux-thunk我想收到帖子。要接收帖子,我需要获得用户。所以我对我的thunk有疑问,在一个thunk中获取所有数据是否正确,如果不是如何将其拆分为两个thunk? Thunk
我有一个改编自 Redux 文档的基本 thunk Action 创建器和 reducer :http://redux.js.org/docs/advanced/AsyncActions.html /
我是一名优秀的程序员,十分优秀!