node-modules / utility

A collection of useful utilities.
Other
1.24k stars 160 forks source link

Arguments to array #21

Closed dead-horse closed 8 years ago

mention-bot commented 8 years ago

By analyzing the blame information on this pull request, we identified @fengmk2 and @alsotang to be potential reviewers

codecov-io commented 8 years ago

Current coverage is 98.87%

Merging #21 into master will increase coverage by +0.02% as of 543c014

@@            master     #21   diff @@
======================================
  Files           12      12       
  Stmts          262     267     +5
  Branches         0       0       
  Methods          0       0       
======================================
+ Hit            259     264     +5
  Partial          0       0       
  Missed           3       3       

Review entire Coverage Diff as of 543c014

Powered by Codecov. Updated on successful CI builds.

fengmk2 commented 8 years ago

@dead-horse 这个 arguments to args 是无法通过额外调用 function 来优化的,只能通过3行代码来优化,没有别的方式了。

fengmk2 commented 8 years ago

测试代码 optimized-test.js

'use strict';

// http://dev.zm1v1.com/2015/08/19/javascript-optimization-killers/?spm=0.0.0.0.Rxyzi2

// 包含需要审查的用法的函数 (这里是 with 语句)
function argumentsToArray(args) {
  var res = new Array(args.length);
  for (var i = 0; i < args.length; i++) {
    res[i] = args[i];
  }
  return res;
  // return 3;
  // try {} catch (e) {}
  // with({}) { }
}

// function testFn() {
//   var res = argumentsToArray(arguments);
//   console.log(res.length);
//   return res.length;
// }

function testFn() {
  var res = new Array(arguments.length);
  for (var i = 0; i < arguments.length; i++) {
    res[i] = arguments[i];
  }
  console.log(res.length);
  return res.length;
}

// function testFn() {
//   // var res = [].slice.call(arguments);
//   var res = Array.prototype.slice.apply(arguments);
//   console.log(res.length);
//   return res.length;
// }

function printStatus(fn) {
  switch(%GetOptimizationStatus(fn)) {
    case 1: console.log("Function is optimized"); break;
    case 2: console.log("Function is not optimized"); break;
    case 3: console.log("Function is always optimized"); break;
    case 4: console.log("Function is never optimized"); break;
    case 6: console.log("Function is maybe deoptimized"); break;
  }
}

// 告诉编译器类型信息
testFn();
// 为了使状态从 uninitialized 变为 pre-monomorphic, 再变为 monomorphic, 两次调用是必要的
testFn();

%OptimizeFunctionOnNextCall(testFn);
// 下一次调用
testFn();

// 检查
printStatus(testFn);

// $ node --trace_opt --trace_deopt --allow-natives-syntax optimized-test.js
dead-horse commented 8 years ago

benchmark 差距很大啊,感觉看 v8 的这个优化选项意义不大。。

dead-horse commented 8 years ago
// arguments to array Benchmark
// node version: v4.2.4, date: Thu Apr 07 2016 01:04:11 GMT+0800 (CST)
// Starting...
// 3 tests completed.
//
// Array.prototpye.slice.call x    578,606 ops/sec ±1.87% (82 runs sampled)
// [].slice.call              x    584,230 ops/sec ±1.23% (87 runs sampled)
// utility.argumentsToArray   x 16,019,542 ops/sec ±1.98% (83 runs sampled)
fengmk2 commented 8 years ago

+1

fengmk2 commented 8 years ago

1.7.0

fengmk2 commented 8 years ago

cc @JacksonTian 看看

dead-horse commented 8 years ago

裸写的性能确实要更好,但是是同一个数量级了,感觉封装起来也没问题。

  Array.prototpye.slice.call x    547,531 ops/sec ±2.89% (81 runs sampled)
  [].slice.call              x    581,149 ops/sec ±1.64% (87 runs sampled)
  raw                        x 40,202,691 ops/sec ±2.88% (81 runs sampled)
  utility.argumentsToArray   x 13,458,873 ops/sec ±4.28% (73 runs sampled)
alsotang commented 8 years ago

如果跟裸写一个数量级的话,我觉得差别就不大。都是千万级的。

但是这个函数名好丑。。。。。

JacksonTian commented 8 years ago

这个优化多一层函数调用,没手写好。

其实v8 5.0之后的rest parameters会比较好用。

function (...args) {
  // args just an array.
}
dead-horse commented 8 years ago

@JacksonTian 等 6 出来就默认支持了吧?4 里面要设置 harmoy 才能用。。

fengmk2 commented 8 years ago

rest parameters v8 已经回默认优化了?

JacksonTian commented 8 years ago

4.9里实现。5.0里有优化。