与表查找功能代替(Replacing functions with Table Lookups)

2019-08-03 16:59发布

我一直在看与布赖恩·贝克曼这个MSDN视频 ,我想更好地了解的东西,他说:

每imperitive程序员经过学习的这个阶段,其功能可与表查找替换

现在,我是一个C#程序员谁没上过大学,所以一路上我错过了每个人都行也许别的地方学会了理解。

什么是布莱恩的意思是:

的功能可以与表查找来代替

是否有正在做的这个实际例子和它适用于所有的功能呢? 他给出的正弦函数,我可以做的意义的例子,但我怎么做的这个意义上说更一般地说?

Answer 1:

布赖恩只是还表明,功能是数据量太大。 在一般功能仅仅是到另一个组映射: y = f(x)是组映射{X}设置{Y}: f:X->Y 。 该表是映射,以及: [x1, x2, ..., xn] -> [y1, y2, ..., yn]

如果功能上有限集进行操作(这是在编程的情况下),那么它可以用代表该映射表代替。 由于布赖恩提到的每一个程序员必须经历的理解这个阶段,该功能可以只为性能原因,查表所取代。

不过,这并不意味着所有的功能,可以轻松地或者应与表取代。 它只是意味着你在理论上可以做到,对于每一个功能。 所以结论是,该功能是数据,因为表是(当然在编程的情况下)。



Answer 2:

有数学中一个可爱的把戏,创建一个表作为评估函数调用,作为重写规则的副作用。 考虑经典慢,斐波那契

fib[1] = 1
fib[2] = 1
fib[n_] := fib[n-1] + fib[n-2]

前两行创建用于输入1及2表项这是完全一样的话说

fibTable = {};
fibTable[1] = 1;
fibTable[2] = 1;

在JavaScript中。 数学的第三行显示“请安装重写规则将替换的任何发生fib[n_]取代图案可变后n_与发生的实际的参数,用fib[n-1] + fib[n-2] “。 重写器将迭代该过程,并最终产生的值fib[n]重写的指数数之后。 这就像递归函数调用的形式,我们在JavaScript中获得与

function fib(n) {
  var result = fibTable[n] || ( fib(n-1) + fib(n-2) );
  return result;
}

注意它首先检查了两个值我们已经明确地做递归调用之前存储在表。 Mathematica的评估会自动执行此检查,因为规则呈现的顺序很重要 - 数学检查更具体的规则第一和更多的一般规则后。 这就是为什么数学有两种分配形式, =:= :前者是具体的规则,其右手边可以在规则规定的时间进行评估; 后者是一般规则,其右手边在应用规则时,必须进行评估。

现在,在数学,如果我们说

fib[4]

它被改写成

fib[3] + fib[2]

然后

fib[2] + fib[1] + 1

然后

1 + 1 + 1

终于到3,这不会对下一个改写改变。 你可以想像,如果我们说的fib[35]我们将产生巨大的表现,填补了内存和融化的CPU。 但关键是用下面的替换最终重写规则:

fib[n_] := fib[n] = fib[n-1] + fib[n-2]

这是说“请更换的每个实例fib[n_]与表达,将安装新的特定规则的价值fib[n]同时,产生的价值。” 这一个运行得更快,因为它扩展的规则库 - 值的表! - 在运行时。

我们可以在JavaScript这样做

function fib(n) {
  var result = fibTable[n] || ( fib(n-1) + fib(n-2) );
  fibTable[n] = result;
  return result;
}

这将运行要比FIB事先定义更快。

这就是所谓的“automemoization” [原文如此 - 没有“记忆”,而是“记忆化”在为自己创建备忘录。

当然,在现实世界中,你必须管理得到创建表的大小。 要检查在数学表,做

DownValues[fib]

为了检查它们在JavaScript中,做到这

fibTable

在一个REPL诸如由Node.js的支持



Answer 3:

在函数式编程的背景下,有引用透明的概念。 即引用透明的函数可以与它的值被替换为任何给定的参数(或一组参数),在不改变程序的行为。

引用透明

例如,考虑函数F是需要1个参数n。 F是引用透明,所以F(n)的可以被F的以n计算的值来代替。 这使得该程序没有区别。

在C#中,这将是这样的:

public class Square
{
    public static int apply(int n)
    {
        return n * n;
    }

    public static void Main()
    {
        //Should print 4
        Console.WriteLine(Square.apply(2));
    }
}

(我不是很熟悉C#,从Java背景的,所以你必须原谅我,如果这个例子是不是很语法正确)。

很明显这里说的功能应用不能超过4任何其他值时为2的参数调用,因为它只是返回其参数的平方。 该函数的值取决于它的参数,N; 换句话说,引用透明。

我问你,那么,有什么区别之间Console.WriteLine(Square.apply(2))Console.WriteLine(4) 答案是,没有任何区别可言,对于所有意图的目的。 我们可以完成整个程序,替换的所有实例Square.apply(n)与返回的值Square.apply(n)其结果将是完全一样的。

那么,什么也布赖恩·贝克曼表示与他有关与表查找替换函数调用语句? 他指的是引用透明功能这个属性。 如果Square.apply(2)可以被替换为4对程序的行为没有任何影响,那么为什么不只是缓存,当第一个调用时的值,并把它放在由函数的自变量索引的表。 对于值的查找表Square.apply(n)会看起来有点像这样:

              n: 0 1 2 3 4  5  ...
Square.apply(n): 0 1 4 9 16 25 ...

而对于任何呼叫Square.apply(n)而不是调用该函数,我们可以简单地找到了在该表n中的缓存值,并替换函数调用这个值。 这是相当明显,这很可能会导致程序中的一个大的速度增加。



文章来源: Replacing functions with Table Lookups