LazyEvaluation的性能优势从何而来? [英] Where exactly does the performance advantage of LazyEvaluation emerge from?

查看:68
本文介绍了LazyEvaluation的性能优势从何而来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几天中,我主要在性能方面研究了LazyEvaluation,想知道 LazyEvalutaion的性能优势从何而来.

In the past few days, I have researched LazyEvaluation, in performance aspect mostly, wondering from where the performance advantage of LazyEvalutaion emerges.

对我来说,阅读各种文章还很不清楚,但其中包括几篇文章

It's been so unclear to me reading various articles but a very few including

懒惰评估有哪些优势?

What are the advantages of Lazy Evaluation?

这是指对语法树的评估.如果您评估 懒惰的语法树(即,当需要它表示的值时), 必须在其计算的前面步骤中进行操作 整体.这是惰性评估的开销.但是,有 两个优点. 1)如果 结果从未使用

This refers to the evaluation of a syntax tree. If you evaluate a syntax tree lazily (i.e. when the value it represents is needed), you must carry it through the preceeding steps of your computation in its entirety. This is the overhead of lazy evaluation. However, there are two advantages. 1) you will not evaulate the tree unnecessarily if the result is never used,

例如,

JavaScript实现了 if 语法.

if(true)
{
    //to evaluate
}
else
{
    //not to evaluate
}

在这种普通情况下,我们没有任何性能问题.

In this ordinary scenario, we don't have any performance issue.

待评估已完成,不待评估在语法树中被忽略.

To be evaluated is done, not to be evaluated is ignored in the syntax tree.

但是,在某些递归循环中,例如, Tak函数又称为Tarai函数

However, in some recursive loop, for instance, Tak function AKA Tarai function

函数tak(x,y,z){ 返回(x< = y)吗? y: tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y)); }

function tak(x,y,z){ return (x <= y) ? y : tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y)); }

由于JS急切的评估策略评估功能(参数)的必然性, 如果-否则-待评估控件不再起作用,并且 tak函数的评估步骤数激增.

Since Eager Evaluation strategy of JS evaluates function(arguments) inevitability, the if - else - not to be evaluated control no longer works, and the number of evaluation step of tak function explodes.

针对(JS或其他语言的)急切评估的缺点,Haskell可以毫无问题地评估 tak 以及某些JS库,例如

Against to this disadvantage of Eager Evaluation(of JS or other languages), Haskell can evaluate the tak without problems as it is, and some JS library such as lazy.js outperforms in a specific area like functional programming where recursive list management required.

除无限列表外,我了解这是LazyEvaluation发挥性能优势的确切原因.我说得对吗?

Aside from infinite list, I understand this is the exact reason for performance advantage of LazyEvaluation. Am I correct?

推荐答案

我认为您有正确的主意.

I think you've got the right idea.

我认为您不需要所有的复杂性.想象一下JavaScript是

I don't think you need all the complexity though. Imagine that the JavaScript was

if (veryExpensiveFunction()) {
  doThis();
} else {
  doThat();
}

现在想象实现了veryExpensiveFunction.

function veryExpensiveFunction() {
   return true || evenMoreExpensiveFunction();
}

如果JavaScript是因为||是惰性的(仅在需要时才评估第二个参数),这将很快返回(因为true是正确的!).如果它是像

If JavaScript because || is lazy (only evaluates the second argument if needed) this will return very quickly (because true is, well, true!). If it was implemented instead like

function veryExpensiveFunction() {
  var a = true;
  var b = evenMoreExpensiveFunction(); // forces the evaluation

  return a || b;
}

这可能需要花费很多时间,因为您不必要地评估了参数.现在,假设应用于||的魔术已应用于每个函数(即一种惰性语言),并且您可能可以想象惰性可能带来的性能优势.

This would take ages to evaluate because you've unnecessarily evaluated the arguments. Now imagine that the magic applied to || was applied to every function (i.e. a lazy language) and you can probably imagine the sort of performance advantages that laziness might bring.

在您的示例中

function tak(x,y,z){ return (x <= y) ? y : tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y)); }

让我们想象一切都是懒惰的.

Let's imagine that everything was lazy.

 var a = tak(1,2,3);

这没有做任何事情(不需要评估). a未使用,因此没有任何评估.

This doesn't do anything (nothing needs to be evaluated). a isn't used, so nothing is evaluated.

 var a = tak(1,2,3);
 console.log(a);

现在我们可以推动对tak的评估了.根据需要获取结果进行评估,我们首先将中的值替换为(将变量替换为其参数).然后,我们评估条件,然后评估我们所需条件的一侧.

Now we're in a position to drive the evaluation of tak. Evaluating as we need to get the results, we first substitute the values in (replace variables with their arguments). We then evaluate the condition, and then only the side of the conditional that we need.

 console.log((1 <= 2) ? 2 : tak(tak(1-1, 2, 3), tak(2-1, 1, 3), tak(3-1, 1, 2));
 console.log(   true  ? 2 : tak(tak(1-1, 2, 3), tak(2-1, 1, 3), tak(3-1, 1, 2));
 console.log(2);

在此示例中(假设我没有做过任何可怕的错别字),那么我们除了参数之外无需评估其他任何东西,并且不进行递归调用.

In this example (assuming I've not made any horrible typos), then we don't need to evaluate anything else other than the arguments and no recursive calls are made.

这篇关于LazyEvaluation的性能优势从何而来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆