JavaScript中对循环语句的优化技巧深入探讨(5)

这里我们来看看一种更给力的解决方案。 如果一个业务环节中需要对大数据集进行迭代处理,而这个数据集从开始迭代起,数据量不会再改变, 那麼可以考虑採用一种名为 duff 装置的技术。这项技术是以其的创造者 tom duff 的名字来命名的, 这项技术最先实现於 c 语言。后来 jeff greenberg 将其移植到 javascript 中,并经过 andrew b. king 修改并提出了一种更为高效的版本。

复制代码 代码如下:


//credit: Speed Up Up Your Site (New Riders, 2003)
var iterations = Math.floor(values.length / 8);
var leftover = values.length % 8;
var i = 0;

if (leftover > 0) {
  do {
    process(values[i++]);
  } while (--leftover > 0);
}
do {
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
  process(values[i++]);
} while (--iterations > 0);

这种技术的工作原理是通过计算values的长度除以 8 以得到需要迭代的次数,并以math.floor()函数来保证结果为整数, 然后再计算不能被 8 整除时的餘数,并对这些元素单独进行处理,其餘则 8 次为单次展开次数来进行迭代。

我将这种装置再加以封装,可以得到一种带有异步味道的 api。

复制代码 代码如下:


function duff(array, mapper) {
  var n = Math.floor(array.length / 8);
  var l = array.length % 8;

var i = 0;
  if (l > 0) {
    do {
      mapper(array[i++]);
    } while (--i > 0);
  }
  do {
    mapper(array[i++]);
    mapper(array[i++]);
    mapper(array[i++]);
    mapper(array[i++]);
    mapper(array[i++]);
    mapper(array[i++]);
    mapper(array[i++]);
    mapper(array[i++]);
  } while (--n > 0);
}

duff([...], function(item) {
  //...
});

这里是一组对於以上三种迭代解决方案的性能测试及其结果。

5.2 非原生循环

在任何编程语言中,能够实现循环的,不止语言所提供的原生循环语句,还可以通过其他方式来间接实现。

让我们先来温习一下高中数学的一点内容——数列的通项公式。

复制代码 代码如下:


bacause
  a[1] = 1
  a[n] = 2 * a[n - 1] + 1

so
                   a[n] + 1 = 2 * a[n - 1] + 2
                            = 2 * (a[n - 1] + 1)
(a[n] + 1) / (a[n - 1] + 1) = 2

then
  a[n] + 1 = (a[n] + 1) / (a[n - 1] + 1) * (a[n - 1] + 1) / (a[n - 2] + 1) * ... * (a[2] + 1) / (a[1] + 1) * (a[i] + 1)
  a[n] + 1 = 2 * 2 * ... * 2 * 2
  a[n] + 1 = 2^n
      a[n] = 2^n - 1

final
  a[n] = 2^n - 1

看了上面这段简单的演算,估计你也猜到我们将要讨论的内容了吧。 是的,我们还可以使用递归来实现循环。

递归是数学和计算机科学中非常重要的一种应用方法,它是指函数在其使用时调用其自身。

在 node.js 社区中,递归被用来实现一种非常重要的技术:中间件技术。 这是一段尚未公佈的新版本的 webjs 中的中间件实现代码。

复制代码 代码如下:


/**
 * Middlewares run method
 * @param  {String} url Current request url
 * @param  {Object} req the request object
 * @param  {Object} res the response object
 * @param  {Function} out Complete Callback
 * @return {Function}     the server
 */
server.runMiddlewares = function(url, req, res, out) {
  var index = -1;

var middlewares = this._usingMiddlewares;

// run the next middleware if it is exists
  function next(err) {
    index++;

// current middleware
    var curr = middlewares[index];

if (curr) {
      var check = new RegExp(curr.route);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgpjgz.html