Closed LeuisKen closed 5 years ago
你是说,在模板语法里加入这种支持,还是san的实现里这么玩?
类似这种地方,从 path.type === ExprType.ACCESSOR
变为 path.type & ExprType.ACCESSOR
。
那是可以的,其实只是我不太习惯
怎么,你要pr吗
怎么,你要pr吗
都行,看看有没有新同学有兴趣?
都行,看看有没有新同学有兴趣?
这个,应该是没有。
这个修改,我来做吧。 由于不够熟悉源码,可能需要一段时间才能提交 PR。
关于枚举变量优化成位运算这种做法,我想了想,不太赞同。
在 san 的源码搜索 ExprType,用于判断的场合就两种,相等比较与在 switch case 中使用。
switch case 也算相等比较,但是也会有多种 case 对应一种解决方案的地方。
如果要优化成位运算的方式,而不改 switch case,则在我看来,没有必要,因为最终的代码修改,只是将 ===
变成了 &
。
如果把 switch case 改成多层 if,则更只是为了性能;还不如直接用哈希 map 来映射,会快很多。
位运算的优化主要就是为了集合(Set)服务的,要有 |
与 &
两种操作。
react 的副作用类型可以重叠的,angular 的 TNodeFlags 也可以重叠。
对于 san,枚举变量 Expr,从抽象意义上而言,应该是不会重叠的(除非增加别的抽象层)。如果把 ===
改成了 &
,代码意义相当于从类型相同变成了类型集合是否有交集,不太适合目前 Expr 类型的使用方式。
综上,我觉得暂时没有必要改成位运算的方式。
嗯 我也认同你的观点 是否可以做个测试比对一下 看看 === 与 & 的性能能差到多少?我多少有点在意这个收益,另外我也没有这相关的量化数据。
测试结果大致是:
const a0 = 0;
const a1 = 1;
const a2 = 2;
const a3 = 3;
const a4 = 4;
const a5 = 5;
const a6 = 6;
const b0 = 1<<0;
const b1 = 1<<1;
const b2 = 1<<2;
const b3 = 1<<3;
const b4 = 1<<4;
const b5 = 1<<5;
const b6 = 1<<6;
function ifElseFn(n) {
if(n === a0) return a0;
if(n === a1) return a1;
if(n === a2) return a2;
if(n === a3) return a3;
if(n === a4 || n === a5) return a5;
if(n === a6) return a6;
return -1;
}
function bIfElseFn(n) {
if(n & b0) return b0;
if(n & b1) return b1;
if(n & b2) return b2;
if(n & b3) return b3;
if(n & (b4 | b5)) return b5;
if(n & b6) return b6;
return -1;
}
function simpleIfElse(n) {
if(n === a3) {
return a3
}
return n
}
function bSimpleIfElse(n) {
if(n & b3) {
return b3
}
return n
}
const execute = fn => fn(Math.floor(Math.random() * 7))
const aMap = { 0: a0, 1: a1, 2: a2, 3: a3, 4: a4, 5: a5, 6: a6 }
const bMap = { 0: b0, 1: b1, 2: b2, 3: b3, 4: b4, 5: b5, 6: b6 }
// const Benchmark = require('benchmark')
const suite = new Benchmark.Suite;
suite
.add('if-else', () => execute(num => ifElseFn(aMap[num])))
.add('bit-if-else', () => execute(num => bIfElseFn(bMap[num])) )
.add('simple-if-else', () => execute(num => simpleIfElse(aMap[num])))
.add('bit-simple-if-else', () => execute(num => bSimpleIfElse(bMap[num])))
.on('cycle', event => {
console.log(String(event.target));
})
.on('complete', function complete() {
console.log(`Fastest is ${this.filter('fastest').map('name')}`);
})
.run({ 'async': true });
if-else x 32,846,167 ops/sec ±0.56% (59 runs sampled)
bit-if-else x 34,814,547 ops/sec ±1.13% (59 runs sampled)
simple-if-else x 83,446,393 ops/sec ±4.00% (56 runs sampled)
bit-simple-if-else x 75,476,747 ops/sec ±5.44% (50 runs sampled)
Fastest is simple-if-else
# 测试结果来自 Chrome 77
ok,这么看的话性能收益也不够。
非常细致的工作,赞 @qianliu013 @LeuisKen
高级
之前和 @errorrik 讨论过这个问题,是否将枚举的判等从
===
优化成&
。当时的结论是:
不过最近看到,angular 和 react 的源码中都有这种应用了。
JavaScript社区中对这种玩法总结了如下优点:
参考:https://youtu.be/_VHNTC67NR8
所以我们是否也可以考虑引入这个写法呢?