作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


对比C/C++, golang等类型安全的语言会在数组访问的代码前,通过编译器加入边界检查的代码。

当发生越界的时候,引发panic,而不是实际发生越界导致的结果异常甚至程序崩溃。

因此,本实验通过对比有边界检查和无边界检查的情况,对比边界检查带来的性能开销:

// 有边界检查的情况
func Benchmark_arr_range_check_1(b *testing.B) {
arr := make([]byte, 1024*1024)
index := make([]int, 1024*32)
for i := 0; i < len(index); i++ {
index[i] = rand.Intn(len(arr))
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
for i := 0; i < len(index); i++ {
arr[index[i]]++ //普通的数组访问,每次访问数组的耗时大约是 1.44ns
}
}
} // 无边界检查的情况
func Benchmark_arr_range_check_2(b *testing.B) {
arr := make([]byte, 1024*1024)
index := make([]int, 1024*32)
for i := 0; i < len(index); i++ {
index[i] = rand.Intn(len(arr))
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
for i := 0; i < len(index); i++ {
offset := index[i]
(*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&arr[0])) + uintptr(offset))))++ // 通过unsafe代码来绕过边界检查,每次数组访问耗时大约 1.41ns
}
}
}
  • 总结:

    • 当涉及大量数组访问的场合,比如很大的定长 local cache的情形,可以通过unsafe去掉边界检查
    • 当某个算法使用查表法来获取数据,适合去掉边界检查

【小测试】golang中数组边界检查的开销大约是1.87%~3.12%的更多相关文章

  1. 🏆【Java技术专区】「编译器专题」重塑认识Java编译器的执行过程(消除数组边界检查+公共子表达式)!

    前提概要 Java的class字节码并不是机器语言,要想让机器能够执行,还需要把字节码翻译成机器指令.这个过程是Java虚拟机做的,这个过程也叫编译.是更深层次的编译. 在编译原理中,把源代码翻译成机 ...

  2. golang中数组指针与指针数组的区别实现

      指针数组和数组的指针,指的是两个不同的东西. 指针数组是有指针组成的数组,数组的指针是一个数组的指针. package main import "fmt" const MAX ...

  3. golang中数组与切片的区别

    初始化:数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变 数组: a := [...],,} a := [],,} 切片: a:= [],,} a := make([]) a := m ...

  4. golang中数组指针和指针数组的区别

    func test(){ x,y := 1, 2 var arr = [...]int{5:2} //数组指针 var pf *[6]int = &arr //指针数组 pfArr := [. ...

  5. golang中数组指针和指针数组当做函数参数如何修改数组中的值

    先理解:数组指针它的类型时指针,指针数组它的类型时数组 1. 数组指针当做函数的参数 package main import "fmt" func changeData(dataA ...

  6. Golang 入门 : 数组

    数组是指一系列同一类型数据的集合.数组中包含的每个数据被称为数组元素(element),这种类型可以是任意的原始类型,比如 int.string 等,也可以是用户自定义的类型.一个数组包含的元素个数被 ...

  7. [转]Golang 中使用 JSON 的小技巧

    taowen是json-iterator的作者. 序列化和反序列化需要处理JSON和struct的关系,其中会用到一些技巧. 原文 Golang 中使用 JSON 的小技巧是他的经验之谈,介绍了一些s ...

  8. golang中mysql建立连接超时时间timeout 测试

    本文测试连接mysql的超时时间. 这里的"连接"是建立连接的意思. 连接mysql的超时时间是通过参数timeout设置的. 1.建立连接超时测试 下面例子中,设置连接超时时间为 ...

  9. 小程序中监听textarea或者input输入的值动态改变data中数组的对象的值

    Page({ data: { todoLists:[ { detail:"", date:"", location:"", priority ...

  10. 小程序开发之改变data中数组或对象的某一属性值

    前言:在小程序的开发中,我们在view中便利data中数组或对象时,很多情况下需要在js中动态改变数组或者对象中某一香的属性值. 效果图: 我给大家总结了案例如下:   wxml如下: <scr ...

随机推荐

  1. 撬动百亿VRAR产业,让VR们“造”起来

    摘要:四大亮点抢先看,12月28-29日不见不散! 随着5G商用的加速及元宇宙.数字人等概念的兴起,虚拟现实技术作为未来世界的入口,正受到越来越多的关注,也将成为驱动数字经济发展和产业转型升级的关键技 ...

  2. 万字长文|大数据学前准备之Linux入门笔记(附资料)

    对于大数据学习而言,Linux运维可以说是必备的技能.可以不研究的过于高深,但是基本的操作和使用一定要熟练.Linux的学习需要大量的实践,本文从linux的基本知识,实战操作,到常用的指令与软件安装 ...

  3. 火山引擎 DataLeap 一招教你避坑“数据开发”中的资源隔离问题

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在离线数仓开发过程中,研发人员需要根据业务变化,在开发/生产环境中不断切换.解析.调试.以往,企业一般通过人工方式 ...

  4. Java 网络编程 —— 基于 UDP 的数据报和套接字

    UDP 简介 UDP(User Datagram Protocol,用户数据报协议)是传输层的另一种协议,比 TCP 具有更快的传输速度,但是不可靠.UDP 发送的数据单元被称为 UDP 数据报,当网 ...

  5. JDk 与 ADB 环境变量配置

    ### Java环境变量配置 首先,JDK是整个Java的核心,包括了Java运行环境,一推Java工具和Java基础的类库. 网址:https://www.oracle.com/technetwor ...

  6. Rust Installation with relative Configuration

    References Rust Course The Hitchhiker's Guide to Rust mirrors.tuna.tsinghua.edu.cn Rust Crates 拉取慢的解 ...

  7. MongoDB 和 MySQL 之间有何区别?

    MongoDB 和 MySQL 是两个可用于存储和管理数据的数据库管理系统.MySQL 是一个关系数据库系统,以结构化表格格式存储数据.相比之下,MongoDB 以更灵活的格式将数据存储为 JSON ...

  8. OS | 透过 inode 来理解硬链接和软链接

    什么是inode? 每个文件都对应一个唯一的inode,inode用来存储文件的元信息,包括: 对应的文件 文件字节数 文件数据块的位置 文件的inode号码 文件的硬链接数 文件的读写权限 文件的时 ...

  9. vue项目部署的最佳实践

    前言 使用vue.react.angular等技术开发过程中,我们都会遇到以下问题: 首屏加载慢 每一次更新都需要清除浏览器缓存才能看到效果(经常被测试吐槽) 这两个问题可以从很多方面进行优化,今天我 ...

  10. nextTick用法