标签: lazy-evaluation

在Scala中初始化伴随对象值的规则

我的游戏有一个像这样的声音对象:

object Sounds {
  SoundFactory.setAssetBasePath("mfx/")

  val EXPLOSION_0 = ESound("explosion1.ogg")
  val EXPLOSION_1 = ESound("explosion2.ogg")
  val EXPLOSION_2 = ESound("explosion3.ogg")
  val IMPACT_0 = ESound("impact1.ogg", 0.4f)
  val IMPACT_1 = ESound("impact2.ogg", 0.4f)
  val IMPACT_2 = ESound("impact3.ogg", 0.4f)
  val BONUS = ESound("bonus.ogg", 0.7f)

  // -- snip --

  def load() {
    println("Sounds loaded")
  }

  case class ESound(sound_file: String, volume: Float = 1) {
    private val sound = SoundFactory.createSoundFromAsset(AndEngine.engine.getSoundManager, AndEngine.activity.get, sound_file)
    sound.setVolume(volume)
    sound.setLoopCount(0)

    def play() { sound.play() }
  }
}
Run Code Online (Sandbox Code Playgroud)

为简洁起见,我删除了许多方法等.但基本的想法是Scala懒惰地load()将对象初始化,所以我第一次在这个对象上调用一些方法()它会被初始化.这将在例如纹理加载等之后完成.

但是使用上面的代码,我第一次按下游戏中的某个菜单按钮时,我得到一个长时间的停顿,因为它只会加载所有这些声音(由SoundFactory.createSound...构造函数中的引起).

现在,如果我将load …

scala initialization lazy-evaluation lazy-initialization

2
推荐指数
1
解决办法
2393
查看次数

Clojure压扁和懒惰

不确定在构造延迟序列时使用flatten时我观察到的行为是什么.

查看clojure.core中的源代码,我可以看到flatten函数调用filter,因此应该返回一个惰性序列 - 我想.但是下面的代码片段给了我一个stackoverflow错误.在使用对concat的调用替换对flatten的调用的代码段中,它工作得很好

(defn l-f [c]
  (if (nil? c) []
    (lazy-seq  (flatten (cons  [[ :h :j] :a :B] (l-f (rest c))))))) 


    (take 10 (l-f (repeat 2))) is how I invoke it.
Run Code Online (Sandbox Code Playgroud)

这是一个相当人为的例子.我也知道flatten和concat会给我一些嵌套级别不同的序列.

我试图找出为什么flatten似乎打破了懒惰,即使我对clojure.core中的代码的(有限的)理解建议不然.

clojure lazy-evaluation flatten

2
推荐指数
1
解决办法
930
查看次数

为什么使用fromMaybe提取IO(Maybe Bool)会执行两个IO操作

在这段代码中:

 fromMaybe <$> (print "A" >> return True) <*> (print "B" >> (return $ Just False))
 fromMaybe <$> (print "A" >> return True) <*> (print "B" >> (return $ Nothing))
Run Code Online (Sandbox Code Playgroud)

我预计,由于懒惰,"A"或"B"将被打印,这取决于我是否提供Just something或者Nothing两者都打印,无论如何.有人可以解释一下这里到底发生了什么?和b)我怎样才能达到我想要的效果?

io haskell lazy-evaluation

2
推荐指数
1
解决办法
266
查看次数

C#懒惰执行+内存理解

你可以告诉我在执行以下代码时内存中发生了什么:

情况1:

public static void Execute()
{
    foreach(var text in DownloadTexts())
    {
          Console.WriteLine(text);
    }
}


public static IEnumerable<string> DownloadTexts()
{
     foreach(var url in _urls)
     {
         using (var webClient = new WebClient())
         {
              yield return webClient.DownloadText(url);
         }
     }
}
Run Code Online (Sandbox Code Playgroud)

让我们假设在第一次迭代后我得到html1.

什么时候从内存中清除html1?

  1. 在下一次迭代?
  2. 当foreach结束?
  3. 当功能结束?

谢谢

**编辑**

案例2:

public static void Execute()
{
    var values = DownloadTexts();
    foreach(var text in values)
    {
          Console.WriteLine(text);
    }
}


public static IEnumerable<string> DownloadTexts()
{
     foreach(var url in _urls)
     {
         using (var webClient = new WebClient())
         { …
Run Code Online (Sandbox Code Playgroud)

c# memory lazy-evaluation yield-return

2
推荐指数
1
解决办法
251
查看次数

在案例类中def vs lazy val

我有一个DAO对象,我将其定义为案例类.

case class StudentDAO(id: Int) {
  def getGPA: Double = // Expensive database lookup goes here
  def getRank: Int = // Another expensive database operation and computation goes here
  def getScoreCard: File = // Expensive file lookup goes here
}
Run Code Online (Sandbox Code Playgroud)

我自然会制作getGPAgetRankgetScoreCard def不是vals因为我不希望它们在被使用之前被计算出来.

如果我将这些方法标记为lazy vals而不是defs,会对性能产生什么影响?我想让它们成为lazy vals 的原因是:我不想每次为id为"i"的学生重新计算等级.

我希望这不会被标记为重复,因为有几个问题如下,主要是差异:

何时在Scala中使用val,def和lazy val?

def或val或lazy val用于语法规则?

Scala中的`def` vs`val` vs`lazy val`评估

斯卡拉懒惰的问题

这个问题主要是针对朝费用(CPU与内存之间的权衡)在作出method一个lazy val昂贵的操作,什么会建议一个比其他?为什么?

编辑:感谢您对@ om-nom-nom的评论.我应该更清楚我正在寻找什么.

我在这里读到:

使用lazy …

scala function lazy-evaluation

2
推荐指数
1
解决办法
3743
查看次数

在进行惰性变量,内存管理时,我们是否需要弱或无主参考?

我正在通过以下方式在Swift中尝试内存管理.

class Person {
    let name: String
    //var block: (() -> Void)?

    init(name: String) {
        self.name = name
    }

    //  Declare variable clone, using self inside.
    private lazy var clone: String  = {
        return self.name   
    }()

    deinit {
        print("Destroying \(name)")
    }
    func doSomething() {
        print("Doing something for \(name)")
    }
}

var p2: Person? = Person(name: "p2")
print(p2!.clone)
p2 = nil
Run Code Online (Sandbox Code Playgroud)

如你所见,我self在声明一个懒惰的var时使用内部,我认为它仍然可以,因为当p2变为nil时,我可以看到该deinit方法被调用.

但是,如果我做了如下更改

    // This is a closure
    private lazy var clone: () -> String  = { …
Run Code Online (Sandbox Code Playgroud)

memory-leaks memory-management lazy-evaluation swift

2
推荐指数
1
解决办法
1066
查看次数

使用Spring @Lazy和@PostConstruct注释

我有以下课程:

@Repository
class A {

    public void method1() {
        ...
    }
}

@Component
class B implements C {

    @Autowired
    @Lazy
    private A a;

    public void method2() {
        a.method1();
    }
}

@Component
class D {

    @Autowired
    private List<C> c;

    @PostConstruct
    public void method3() {
        // iterate on list c and call method2()
    }
}
Run Code Online (Sandbox Code Playgroud)

让我们假设Spring将bean初始化如下:
1.创建第一个bean B. 当创建bean B时,a由于@Lazy注释,将不会初始化字段.
2.创建下一个bean D. 然后method3()将被标记为执行@PostConstruct,但Spring尚未触及bean A. 因此,当调用a.method1()时,Spring会创建bean A并将其注入字段中a还是会抛出NullPointerException

java spring annotations lazy-evaluation postconstruct

2
推荐指数
1
解决办法
4148
查看次数

Haskell键输入内存泄漏

我想出了原始输入问题的以下代码,正如SO Haskell中读到的原始键盘输入所讨论的那样.不幸的是,当我去ghci,运行getAllInput并点击右箭头键时,它永远不会返回.除非我很快就杀了它,它似乎占用了我所有的内存,以便其他应用程序停止响应,我必须重新启动操作系统.在活动监视器中,我可以看到ghc进程的内存快速进入千兆字节.

(1)我认为问题出在递归调用中go,通过hReady之前的调用来懒惰地评估getChar; 这意味着hReady保持返回true并且堆栈永远增长.这看起来有道理吗?

(2)我习惯于很快会导致堆栈溢出异常的语言,所以它不会阻止我工作.有没有一般的方法来防止这种大规模的内存泄漏?也许以内存使用的硬限制开始ghci?

import System.IO

-- For example, should get "\ESC[C" from the user hitting the right arrow key.
getAllInput :: IO [Char]
getAllInput =
  let
    go :: IO [Char] -> IO [Char]
    go chars = do
      more <- hReady stdin
      if more then go (added chars getChar) else chars
    added :: IO [Char] -> IO Char -> IO [Char]
    added chars char = do
      chars1 …
Run Code Online (Sandbox Code Playgroud)

haskell memory-leaks lazy-evaluation

2
推荐指数
1
解决办法
200
查看次数

列表连接的性能实现为左侧折叠

考虑将列表连接实现为左侧折叠,即foldl (++) [].在惰性求值语言中,例如Haskell,这种实现的复杂性是什么?我理解,在严格的语言中,表现是元素总数的二次方,但是当涉及懒惰时会发生什么?

我试图用手工评估表达式([1,2,3] ++ [4,5,6]) ++ [7,8,9](对应于foldl (++) [] [[1,2,3], [4,5,6], [7,8,9]]),似乎我们只遍历每个元素一次,但我不确定我的推理是否正确:

([1,2,3] ++ [4,5,6]) ++ [7,8,9]
= { rewrite expression in prefix notation }
(++) ((++) [1,2,3] [4,5,6]) [7,8,9]
= { the first (++) operation needs to pattern match on its first argument; so it evaluates the first argument, which pattern matches on [1,2,3] }
(++) (case [1,2,3] of {[] -> [4,5,6]; x:xs' -> x:(++) xs' [4,5,6]}) [7,8,9]
= { x = …
Run Code Online (Sandbox Code Playgroud)

performance haskell list lazy-evaluation time-complexity

2
推荐指数
1
解决办法
94
查看次数

JavaScript地图并同时查找:findMap?

您将如何在不使用for循环的情况下重写它?

const a = [2, 5, 78, 4];
const expensiveFunction = n => 2 * n;

let result;

// Find the first number 
for (let i = 0; i < a.length; i++) {
    const r = expensiveFunction(a[i]);

    if (r > 100) {
        result = r;
        break;
    }
}

console.log(result);
Run Code Online (Sandbox Code Playgroud)

我的天真做法:

const result = a.map(expensiveFunction).find(x => x > 100);
console.log(result);
Run Code Online (Sandbox Code Playgroud)

但这expensiveFunction涉及所有要素,我想避免。在上述情况下,我们应避免运行expensiveFunction(4)

有些语言具有find_map(例如Rust),我没在lodash或下划线中找到它。

javascript lazy-evaluation

2
推荐指数
1
解决办法
172
查看次数