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


在VM的merge部分的代码中发现这样一个函数:

func commonPrefixLen(a, b []byte) int {
i := 0
if len(a) > len(b) {
for i < len(b) && a[i] == b[i] {
i++
}
} else {
for i < len(a) && a[i] == b[i] {
i++
}
}
return i
}

在merge整个sstable的时候,需要算出所有字符串的公共前缀,然后存储的时候就不再存储公共前缀的部分,这样就实现了进一步的数据压缩。

这个函数调用得非常频繁,于是想尝试用SIMD来优化。

后来试了一下,简单的写法就能提升1.6倍,优化的代码如下:

// macbook pro 2019, Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
// 15.70 ns/op
func commonPrefixLenOneByOne(a, b []byte) int {
i := 0
if len(a) > len(b) {
for i < len(b) && a[i] == b[i] {
i++
}
} else {
for i < len(a) && a[i] == b[i] {
i++
}
}
return i
} // from this issue: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2254
// macbook pro 2019, Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
// 9.785 ns/op when memory aligned, 1.6 times faster
// 9.833 ns/op when memory not aligned
func commonPrefixLen(a, b []byte) int {
if len(a) > len(b) {
a, b = b, a
}
if len(a) < 8 {
return commonPrefixLenOneByOne(a, b)
}
const size = 8
compareTimes := len(a) / size
addrA := uintptr(unsafe.Pointer(&a[0]))
addrB := uintptr(unsafe.Pointer(&b[0]))
for i := 0; i < compareTimes; i++ {
v1 := (*uint64)(unsafe.Pointer(addrA))
v2 := (*uint64)(unsafe.Pointer(addrB))
if *v1 != *v2 {
return i*size + commonPrefixLenOneByOne(a[i*size:], b[i*size:])
}
addrA += size
addrB += size
}
return compareTimes*size + commonPrefixLenOneByOne(a[compareTimes*size:], b[compareTimes*size:])
}

思路就是用unsafe指针把连续的8个byte转换为uint64的指针,这样就可以一条指令比较8个字节。

这个优化已经提了一个PR到VM的仓库:https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2913

【小优化】golang中取两个字符串的公共前缀的长度的更多相关文章

  1. JS 从一个字符串中截取两个字符串之间的字符串

    /************************************************* 函数说明:从一个字符串中截取 两个字符串之间的字符串 参数说明:src_str 原串, start ...

  2. Java 中如何计算两个字符串时间之间的时间差?(单位为分钟)

    Java 中如何计算两个字符串时间之间的时间差?(单位为分钟) import java.text.DateFormat; import java.text.ParseException; import ...

  3. golang中判断两个slice是否相等

    在golang中我们可以轻松地通过==来判断两个数组(array)是否相等,但遗憾的是slice并没有相关的运算符,当需要判断两个slice是否相等时我们只能另寻捷径了. slice相等的定义 我们选 ...

  4. SQL Server中取两个表的交集,并集和差集

    在项目中遇到要取两个表差集的情况 假设有两个表tblNZPostCodes, NZPostcode  两个表中存储的都是新西兰的post code信息,字段一致,只是数据上有所差异. 1. Union ...

  5. java中判断两个字符串是否相等的问题

    我最近刚学java,今天编程的时候就遇到一个棘手的问题,就是关于判断两个字符串是否相等的问题.在编程中,通常比较两个字符串是否相同的表达式是“==”,但在java中不能这么写.在java中,用的是eq ...

  6. SQLServer中求两个字符串的交集(字符串以符号分隔)

    两个字符串,以特定符号分隔(例如‘,’号),求交集 第一种情况: declare @m varchar(100),@n varchar(100)select @m=',2,3,5,7,8,9,10,' ...

  7. 字符串的公共前缀对Mysql B+树查询影响回溯分析

        年前项目组接微信公众号. 上线之后,跟微信相关的用cid列的查询会话的SQL变慢了几十倍!思考这个问题思考了非常久.从出现以来一直是我心头的一个结.cid这一列是建了索引的,普通的cid列更新 ...

  8. Java 中字两个字符串判断是否相等(转载)

    java中判断字符串是否相等有两种方法:1.用"=="运算符,该运算符表示指向字符串的引用是否相同,比如: String a="abc";String b=&q ...

  9. js-获取两个字符串日期的相隔周

    例如说"2017-04-01 23:00:00"是周六, "2017-04-28 23:00:00"是周五,包含各自所在的那一周,我真正需要获得的结果是5个周. ...

  10. 将从数组中取到的字符串赋值给了UIImage导致的错误

    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantStr ...

随机推荐

  1. 海量数据分析快准稳!GaussDB(for MySQL) HTAP只读分析特性详解

    摘要:除了拥有 ClickHouse 本身的极致性能外,GaussDB(for MySQL)的HTAP只读分析在 MaterilizeMySQL引擎的性能和稳定性等方面具有更优秀的表现,为提供更快更准 ...

  2. 万字保姆级长文——Linkedin元数据管理平台Datahub离线安装指南

    ​ 元数据管理平台Datahub最近的热度越来越高.已经更新到了0.8.40的版本,来咨询我的小伙伴也越来越多,特别是安装过程有很多问题. ​ 考虑到有些企业部分数据服务是部署在内网的,那么离线安装D ...

  3. 让 K8s 更简单!8款你不得不知的 AI 工具-Part 1

    介绍 最近,AI 引起了广泛关注,而 Kubernetes 驱动的 DevOps 也不例外.软件工程师是自动化的忠实拥护者,因此针对 Kubernetes 操作员的 AI 驱动工具自然也开始涌现. 这 ...

  4. Kubernetes(K8S) 监控 Prometheus + Grafana

    监控指标 集群监控 节点资源利用率 节点数 运行Pods Pod 监控 容器指标 应用程序 Prometheus 开源的 监控.报警.数据库 以HTTP协议周期性抓取被监控组件状态 不需要复杂的集成过 ...

  5. 一个IT老码农的创业和生活(一)抑郁和自杀

    2019年2月18日,离我的38周岁生日还差两个月,我的编程培训班"源栈"开张了.   在此之前,从我2002年大学毕业,6年时间,我先后做过英语教师.实习律师.公司法务.装修公司 ...

  6. 一个非常轻量级的 Web API Demo

    一个非常轻量级的 Web API Demo,代码量很少,实现了方法拦截器,token校验,异常拦截器,缓存 创建项目:如果选择Web API,项目中东西会比较多,这里选择Empty,把下面的Web A ...

  7. JSP | IDEA 配置 JSP 模板

    新建 jsp 文件时的模板 在第 5 步输入下面模板代码: <%-- Created by IntelliJ IDEA. User: ${USER} Date: ${DATE} Time: ${ ...

  8. Kafka 原理以及分区分配策略剖析

    一.简介 Apache Kafka 是一个分布式的流处理平台(分布式的基于发布/订阅模式的消息队列[Message Queue]). 流处理平台有以下3个特性: 可以让你发布和订阅流式的记录.这一方面 ...

  9. 写了个移动端可滑动(惯性滑动&回弹)Vue导航栏组件 ly-tab

    https://www.imooc.com/article/23768?block_id=tuijian_wz https://blog.csdn.net/weixin_44614772/articl ...

  10. kubernetes scc 故障排查小记

    1. 故障现象 环境在跑自动化测试时打印 error: [ ERROR ] Opening output file '/output.xml' failed: Read-only file syste ...