美文网首页
Typescript 扩展‘‘位开关’’

Typescript 扩展‘‘位开关’’

作者: Zszen | 来源:发表于2020-03-30 14:35 被阅读0次

位开关

经常开发的小伙伴会经常用到
用起来最方便的是枚举+位开关的方式

const enum DebugType{
    NONE = 0,
    game=1<<0,
    dev=1<<1,
}

var swicher = DebugType.game|DebugType.dev;

这样你的开关都存储在4个字节里, 设置和比较都比较简单

  • 比较
    开关内是否包含某一个或几个开关
swicher&(DebugType.game|DebugType.dev)

同时检测两个开关是否存在

  • 添加
swicher |= DebugType.game

添加game开关

  • 关闭
swicher &= ~DebugType.game

弊端

位开关在枚举下只有最多32个, 扩展它的话靠语言支持的不太通用.

可以自己写个类来融合多个枚举的比较

// TypeScript file

const enum DebugType{
    NONE = 0,
    game=1<<0,
}

const enum GameType{
    NONE = 0,
    play=1<<2,
    gameend=1<<3,
}

const enum ConfigType{
    NONE = 0,
    debug=1<<4,
}

class Switcher{
    lower:number
    middler:number
    upper:number
    public constructor(lower:number=0, middler:number=0, upper:number=0){
      this.lower = lower
      this.middler = middler
      this.upper = upper
    }

    public cmp(lower:DebugType=0, middler:GameType=0, upper:ConfigType=0) {
        return this.lower&lower || this.middler&middler || this.upper&upper
    }
}

const a1 = new Switcher(DebugType.game, GameType.gameend|GameType.play)

const a2 = DebugType.game
const b2 = GameType.gameend|GameType.play
const c2 = ConfigType.NONE

const a3 = {}
a3[ConfigType.debug] = true

const a4 = []
a4[GameType.gameend] = true

const loopTimes = 100000000

var t
t = egret.getTimer()
for(let k=0;k<loopTimes;k++){
  a1.cmp(DebugType.game, GameType.NONE, ConfigType.debug)
}
console.log(`使用扩展类用时 ${egret.getTimer()-t} ms`);

t = egret.getTimer()
for(let k=0;k<loopTimes;k++){
  a2&DebugType.game || b2&GameType.NONE || c2&ConfigType.debug
}
console.log(`直接使用开关用时 ${egret.getTimer()-t} ms`);

// t = egret.getTimer()
// for(let k=0;k<loopTimes;k++){
//   a3[ConfigType.debug] && a3[DebugType.game] && a3[GameType.play]
// }
// console.log(`使用字典用时 ${egret.getTimer()-t} ms`);

// t = egret.getTimer()
// for(let k=0;k<loopTimes;k++){
//   a4[ConfigType.debug] && a4[DebugType.game] && a4[GameType.play]
// }
// console.log(`使用数组用时 ${egret.getTimer()-t} ms`);

代码可以复制回去测试, 在一亿次的时候, 数组和字典寻址都捉襟见肘, 是前两个方式的10倍+, 其实这个方法慢只慢在跳转到函数地址, 如果语法支持内联(inline) 就把修饰符加上, 速度还会快一些.

总体来讲,也挺灵活的,哈哈。

题外话

为什么这么快
因为位操作用到的是硬件加速, 在cpu中最小的运算单元, 就包含着数不清的比较器, 构成了或门、非门、与非门等, 详情进行扩展阅读

位操作策略
https://www.jianshu.com/p/116cf0ff6a7e
图解门电路
https://www.jianshu.com/p/f0bd155d08d7

相关文章

网友评论

      本文标题:Typescript 扩展‘‘位开关’’

      本文链接:https://www.haomeiwen.com/subject/bacvuhtx.html