[翻译]关于Mathematica提速的几点技巧(三)

8.BlockWith代替Module.

 Block,WithModule都可用来构建局部化结构,它们的各自的特性有略微的不同.以我的经验来看,BlockModule95%的情况下都可以相互替换,但是通常Block会快一点.有些情况下With(变量处于只读状态的Block)会更快.

Do[Module[{x = 2.}, 1/x], {1000000}]; // AbsoluteTiming

{4.1497064, Null}

Do[Block[{x = 2.}, 1/x], {1000000}]; // AbsoluteTiming

{1.4664376, Null}

9.别总用模式匹配

模式匹配很棒,能轻松地编出复杂的程序.遗憾的是,它并不总是最快的,特别是代码里出现”___”等模棱两可的模式时(会浪费大量的时间去检索你早已确定不会出现的模式).如果计算速度优先考虑的话,”_”或者根本不用模式.

data = RandomReal[1, {200}]; data //. {a___, b_, c_, d___} /; b > c → {a, c, b, d}; // AbsoluteTiming

{2.5272648, Null}

(flag = True; While[TrueQ[flag], flag = False; Do[If[data[[i]] > data[[i + 1]], temp = data[[i]]; data[[i]] = data[[i + 1]]; data[[i + 1]] = temp; flag = True], {i, 1, Length[data] - 1}]]; data); // AbsoluteTiming

{0.1716044, Null}

当然,在这种情况下最好的方法还是使用内置函数(我在第三点提到过),完爆冒泡算法”.

Sort[RandomReal[1, {200}]]; // AbsoluteTiming

{0., Null}

10. 横看成岭侧成峰.

Mathematica,完成同一件事总是有很多条途径.编程风格总是跟着问题走,而不必为了迎合单一的编程风格而重新考量问题本身.然而,概念上的简单不总是等同于计算上的高效.有时容易理解的想法会带来很计算上的无用功”.

预测那种方法更高效一般是很困难的,因为Mathematica会自动地进行特别的优化和采用高效的算法.比如,下面两个例子都能计算阶乘,但是显然第二种方法更加快速.

temp = 1; Do[temp = temp i, {i, 2^16}]; // AbsoluteTiming

{0.8892228, Null}

Apply[Times, Range[2^16]]; // AbsoluteTiming

{0.0624016, Null}

为什么会这样?对此你可能会有种种猜测:Do循环太慢?赋值浪费时间?或者其它的一些错误?真正的原因是难以预料到的.Times对大数或大整数有一种二进制分离技巧,比递归地参数分离成较小的乘积更快.这两种情况所作的乘积数是一样的,但是后者更少地操作大整数.有很多像这样不为人知的魔法隐藏在Mathematica,随着版本的更新这种魔法也会越来越多.

当然,最快的方法还是直接使用内置函数:

AbsoluteTiming[65536!;]

{0.0156004, Null}

Mathematica有能力进行卓越性能的计算,也有很高的鲁棒性和精度.虽然这两点一般不能同时拥有.我希望这些技巧能帮助你去达到快速编程,高效计算,和精确结果这三点间的平衡.

 

时间测试所用机器配置: Windows 7 64-bit PC with 2.66 GHz Intel Core 2 Duo and 6 GB RAM.

 

 

 

原文地址:https://www.cnblogs.com/mymma/p/2663873.html