标签: lazy-evaluation

如何减少Haskell应用程序中的内存使用量?

我是函数式编程的新手,现在学习Haskell.作为练习,我决定实现一维线性扩散方程的显式欧拉方法.虽然下面的代码工作正常,但我对它的性能并不满意.事实上,我关心的是内存消耗.我相信它与懒惰评估有关,但无法弄清楚如何减少其内存使用量.

算法的想法非常简单,用命令性的术语表达:它采用一个"数组",并且每个内部点都添加一个值,该值是作为点本身和其中的值的组合计算的.邻居.边界点是特殊情况.

所以,这是我的Euler1D.hs模块:

module Euler1D
( stepEuler
, makeu0
) where

-- impose zero flux condition
zeroflux :: (Floating a) => a -> [a] -> [a]
zeroflux mu (boundary:inner:xs) = [boundary+mu*2*(inner-boundary)]

-- one step of integration
stepEuler :: (Floating a) => a -> [a] -> [a]
stepEuler mu u@(x:xs) = (applyBC . (diffused mu)) u
    where
          diffused mu (left:x:[]) = []    -- ignore outer points
          diffused mu (left:x:right:xs) = -- integrate inner points
                   (x+mu*(left+right-2*x)) : diffused mu (x:right:xs)
          applyBC inner …
Run Code Online (Sandbox Code Playgroud)

garbage-collection haskell functional-programming memory-management lazy-evaluation

32
推荐指数
2
解决办法
8390
查看次数

thunk使用了多少内存?

假设我有一个非常大的数字(数百万/十亿+)这些简单的Foo数据结构:

data Foo = Foo
    { a :: {-# UNPACK #-}!Int
    , b :: Int
    }
Run Code Online (Sandbox Code Playgroud)

随着这么多的浮动,有必要考虑他们消耗多少内存.

在64位机器上,每个Int都是8个字节,因此a只需要8个字节(因为它是严格的和解压缩的).但是会b占用多少内存?我想这会根据thunk是否被评估而改变,对吧?

我想在一般情况下这是不可能的,因为b可能依赖于任何数量的内存位置,只有在b需要评估的情况下才会留在内存中.但是,如果b只依赖(一些非常昂贵的操作)a呢?那么,是否有一种确定性的方式来判断将使用多少内存?

haskell lazy-evaluation thunk

32
推荐指数
2
解决办法
1394
查看次数

dplyr的filter_中的非标准评估(NSE)和从MySQL中提取数据

我想从带有动态过滤器的sql server中提取一些数据.我正在以下列方式使用伟大的R包dplyr:

#Create the filter
filter_criteria = ~ column1 %in% some_vector
#Connect to the database
connection <- src_mysql(dbname <- "mydbname", 
             user <- "myusername", 
             password <- "mypwd", 
             host <- "myhost") 
#Get data
data <- connection %>%
 tbl("mytable") %>% #Specify which table
 filter_(.dots = filter_criteria) %>% #non standard evaluation filter
 collect() #Pull data
Run Code Online (Sandbox Code Playgroud)

这段代码工作正常但现在我想以某种方式在我的表的所有列上循环它,因此我想将过滤器编写为:

#Dynamic filter
i <- 2 #With a loop on this i for instance
which_column <- paste0("column",i)
filter_criteria <- ~ which_column %in% some_vector
Run Code Online (Sandbox Code Playgroud)

然后使用更新的过滤器重新应用第一个代码.

不幸的是,这种方法没有给出预期的结果.实际上它没有给出任何错误,但是甚至没有将任何结果拉入R.特别是,我看了两个代码生成的SQL查询,并且有一个重要的区别.

第一个工作代码生成表单的查询:

SELECT ... FROM …
Run Code Online (Sandbox Code Playgroud)

r lazy-evaluation dplyr

31
推荐指数
3
解决办法
1万
查看次数

Immutable.js或Lazy.js执行捷径融合吗?

首先,让我为那些不认识的人定义什么是捷径融合.在JavaScript中考虑以下数组转换:

var a = [1,2,3,4,5].map(square).map(increment);

console.log(a);

function square(x) {
    return x * x;
}

function increment(x) {
    return x + 1;
}
Run Code Online (Sandbox Code Playgroud)

这里我们有一个数组,[1,2,3,4,5]其元素首先被平方,[1,4,9,16,25]然后递增[2,5,10,17,26].因此,虽然我们不需要中间数组[1,4,9,16,25],但我们仍然创建它.

捷径融合是一种优化技术,它可以通过将一些函数调用合并为一个来消除中间数据结构.例如,可以将快捷融合应用于上述代码以产生:

var a = [1,2,3,4,5].map(compose(square, increment));

console.log(a);

function square(x) {
    return x * x;
}

function increment(x) {
    return x + 1;
}

function compose(g, f) {
    return function (x) {
        return f(g(x));
    };
}
Run Code Online (Sandbox Code Playgroud)

如您所见,通过组合和函数将两个单独的map调用融合到一个map调用中.因此,不创建中间阵列.squareincrement


现在,我理解像Immutable.jsLazy.js这样的库在JavaScript中模仿延迟评估.延迟评估意味着仅在需要时计算结果. …

javascript lazy-evaluation immutable.js lazy.js

31
推荐指数
1
解决办法
2813
查看次数

懒惰和并行性如何在Haskell中共存?

人们认为Haskell在并行性方面具有优势,因为它具有不变的数据结构。但是Haskell也很懒。这意味着实际上可以将数据从thunk突变为评估结果。

因此,懒惰似乎会损害不变性的优势。我是错的还是Haskell有针对此问题的对策?还是这是Haskell的特色?

parallel-processing haskell immutability lazy-evaluation

31
推荐指数
1
解决办法
1296
查看次数

如何在Ruby中获取一个惰性数组?

如何在Ruby中获取一个惰性数组?

在Haskell中,我可以谈论[1..],这是一个无限的列表,根据需要懒洋洋地生成.我也可以做类似的事情iterate (+2) 0,它应用我给它的任何函数来生成一个惰性列表.在这种情况下,它会给我所有偶数.

我确信我可以在Ruby中做这些事情,但似乎无法弄清楚如何.

ruby lazy-evaluation

30
推荐指数
3
解决办法
8705
查看次数

为什么GADT /存在数据构造函数不能用于惰性模式?

今天,当在存在的GADT构造函数上进行匹配时,尝试使用延迟模式时出现编译器错误:

存在或GADT数据构造函数不能在惰性(〜)模式中使用

为什么会有这种限制?如果被允许,会发生什么"坏"的事情?

haskell pattern-matching lazy-evaluation existential-type gadt

30
推荐指数
2
解决办法
703
查看次数

unboxed类型和严格性之间的关系是什么?

未装箱的类型,比如Int#,和严格的功能,f (!x) = ...是不同的,但我看到概念上的相似性 - 他们在某种程度上不允许暴力/懒惰.如果Haskell是像Ocaml这样的严格语言,那么每个函数都是严格的,并且每个类型都是未装箱的.unboxed类型与强制执行之间的关系是什么?

evaluation haskell lazy-evaluation strictness

29
推荐指数
3
解决办法
3598
查看次数

如何在Clojure中实现延迟序列?

我喜欢Clojure.困扰我的一个问题是我不知道如何实现懒惰的序列,或者它们是如何工作的.

我知道懒惰序列只评估序列中要求的项目.它是如何做到的?

  • 什么使得延迟序列如此高效以至于它们不会消耗太多堆栈?
  • 为什么你可以在延迟序列中包装递归调用,并且不再为大型计算获得堆栈溢出?
  • 懒惰序列消耗什么资源来做它做的事情?
  • 在什么情况下懒惰序列效率低下?
  • 在什么情况下懒惰序列最有效?

lisp clojure lazy-evaluation lazy-sequences

29
推荐指数
3
解决办法
3588
查看次数

伊德里斯急切评价

Haskell中,我可能会这样实现if:

if' True  x y = x
if' False x y = y
spin 0 = ()
spin n = spin (n - 1)
Run Code Online (Sandbox Code Playgroud)

表现我的期望:

haskell> if' True  (spin 1000000) ()  -- takes a moment
haskell> if' False (spin 1000000) ()  -- immediate
Run Code Online (Sandbox Code Playgroud)

Racket中,我可以实现这样的缺陷if:

(define (if2 cond x y) (if cond x y))
(define (spin n) (if (= n 0) (void) (spin (- n 1))))
Run Code Online (Sandbox Code Playgroud)

表现我的期望:

racket> (if2 …
Run Code Online (Sandbox Code Playgroud)

evaluation haskell lazy-evaluation expression-evaluation idris

29
推荐指数
1
解决办法
1491
查看次数