特殊情况下,不同取模操作的效率比较

lgf133214 · · 550 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

### 所指代的特殊情况是指 a % b,b 为 2 的 n 次方的情况。 > 额(⊙﹏⊙),作为平时使用的话,完全用不上,在非常巨量的操作下才可能会有差距 - 先拿 10 进制举例,如果 15648615341 % 10,那你肯定立马知道结果是 1,10 变成 100,你也知道结果是 41 - 同样的换成二进制 1110100100101110101110101110101101 % 10 (二进制哦~~),结果是 1(也就表示是奇数),换成 100 结果是 1,1000 ==>> 101 - 所以得出结论 如果 a % b, b 是 2 的次方的时候(也就是可以表示为 1 << n 的数),结果就是 a 的后 n 位。后 n 位可以用 a % (b - 1) 的方式取出 > 下面是测试的代码,不足之处欢迎指正 ```golang package main import ( "math/rand" "testing" "time" ) func BenchmarkModByAnd(b *testing.B) { // 忽略开头的初始化 b.StopTimer() for i := range [100][0]int{} { // 随机种子 rand.Seed(time.Now().Unix()) // 操作数赋值 a := rand.Intn(1000000) c := 1 << (i % 63) // 运算部分 b.StartTimer() // 循环此处忽略不计,如果每次都放到内部消耗CPU,跑不出来 for i := 0; i < b.N; i++ { _ = a & (c - 1) } b.StopTimer() // 结果验证,毕竟是特殊方法嘛 res := a % c r := a & (c - 1) if r != res { b.Fail() } } } /* goos: windows goarch: amd64 BenchmarkModByAnd BenchmarkModByAnd-12 44577350 25.7 ns/op PASS 上为 goland 内部直接运行的测试结果 */ func BenchmarkModNormally(b *testing.B) { b.StopTimer() for i := range [100][0]int{} { rand.Seed(time.Now().Unix()) a := rand.Intn(1000000) c := 1 << (i % 63) b.StartTimer() for i := 0; i < b.N; i++ { _ = a % c } b.StopTimer() } } /* goos: windows goarch: amd64 BenchmarkModNormally BenchmarkModNormally-12 23575406 50.8 ns/op PASS 上为 goland 内部直接运行的测试结果 */ ``` ### 可以看到位运算的效率和直接运算(%)的效率是两倍的关系 ## 但是,如果没达到特别特别大的量级,是看不出区别的┭┮﹏┭┮,仅仅作为知识拓展吧

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

550 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传