11.3重构计算顺序

11.3重构计算顺序

 

      我们已经看了如何在使用不可变数据结构的代码中跟踪函数之间的依赖关系。一旦我们知道了依赖关系是什么,有时就可以重新排序操作,使程序更有效,而保持原有的意义。清单 11.12 显示了这种类型优化的一个简单例子。

 

Listing 11.12 Reordering calculations in a program (C#)

  

var num = Calculate1(10);
var test = TestCondition();
if (test == true)
  return Calculate2(num);
else return 0;

var test = TestCondition();
if (test == true) {
  var num = Calculate1(10);
  return Calculate2(num);
} else return 0;

 

    在第一个版本中,我们在程序开始时调用 Calculate1 函数,而此调用的结果只在 TestCondition 返回 true 时使用。如果不是这样的情况,我们没有任何理由执行 Calculate1 函数,浪费我们的 CPU 时间!在第二个版本中,我们把这个计算移到了 if 条件内,所以,只在需要这个结果时才计算。

    这是一个简单的修改,你可能有写过??更有效的版本,只是没有思考过。随着程序逐渐增长,像这样的优化变得更加难以发现。清单 11.13 显示了一个稍微复杂一些的例子。

 

Listing 11.13 Passing a computed result to a function (C#)

 

int TestAndCalculate(int num) {
  var test = TestCondition();
  if (test == true)
    return Calculate2(num);
  else return 0;
}

TestAndCalculate(Calculate1(10));

 

    在这个例子中,函数取一个值 num 作为一个参数,但这个函数可能根本就不需要这个值。如果条件的计算结果为 false,函数返回 0,num 值是不相关的。当调用此函数时,函数 Calculate1 被执行,即使我们后来发现不需要它的结果。

    在 Haskell(另一种流行的函数式语言)中,此代码不会调用Calculate1,如果它不需要这个结果。因为,Haskell 使用不同的计算策略。在回到优化清单 11.13 之前,让我们看几个选项。

你可能感兴趣的:(优化,table,程序,border,如何)