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


做 profile 发现 url.QueryEscape 占用的 CPU 时间较多,于是搜索到了一个资料:net/url: optimize unescape and escape.

于是在这个代码的基础上改了FastQueryString的版本。

在 Macbook pro m2 上测试:

  • url.QueryEscape() 281.5 ns/op
  • FastQueryEscape() 38.40 ns/op, 快7.33 倍

具体代码如下:query_escape.go

package stringsutil

import (
"bytes"
"reflect"
"unsafe"
) func shouldPathEscape(c byte) bool {
if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' {
return false
}
switch c {
case '-', '_', '.', '~': // = & ':', '@', '+', '$'
return false
}
return true
} var (
shouldEscapeLUT [256]bool
) func init() {
for i := 0; i < 256; i++ {
shouldEscapeLUT[i] = shouldPathEscape(byte(i))
}
} // FastQueryEscape fast version
func FastQueryEscape(s string, buf *bytes.Buffer) []byte {
hexCount := 0
for i := 0; i < len(s); i++ {
if shouldEscapeLUT[s[i]] {
hexCount++
}
}
if hexCount == 0 {
return NoAllocBytes(s)
}
total := len(s) + 2*hexCount
if buf.Cap() < total {
buf.Grow(total * 2)
}
t := buf.Bytes()[:total]
j := 0
for i := 0; i < len(s); i++ {
c := s[i]
if shouldEscapeLUT[c] {
t[j] = '%'
t[j+1] = "0123456789ABCDEF"[c>>4]
t[j+2] = "0123456789ABCDEF"[c&15]
j += 3
} else {
t[j] = c
j++
}
}
return t
} // copy from prometheus source code // NoAllocString convert []byte to string
func NoAllocString(buf []byte) string {
return *(*string)(unsafe.Pointer(&buf))
} // NoAllocBytes convert string to []byte
func NoAllocBytes(buf string) []byte {
// not safe: return *(*[]byte)(unsafe.Pointer(&buf))
x := (*reflect.StringHeader)(unsafe.Pointer(&buf))
h := reflect.SliceHeader{Data: x.Data, Len: x.Len, Cap: x.Len}
// nolint:all
return *(*[]byte)(unsafe.Pointer(&h))
}

使用的时候要重用 bytes.Buffer 对象。例如如下:

var testStr = "a=1&b=2&%%?_-/中文__-_.~:@+$"
// a%3D1%26b%3D2%26%25%25%3F_-%2F%E4%B8%AD%E6%96%87__-_.~%3A%40%2B%24 func TestFastQueryEscape(t *testing.T) {
s := url.QueryEscape(testStr)
t.Logf("%s", s)
target := &bytes.Buffer{}
target.Grow(1024)
out := FastQueryEscape(testStr, target)
t.Logf("%s", NoAllocString(out))
if s != NoAllocString(out) {
t.Error("not match")
}
}

【代码片段分享】比 url.QueryEscape 快 7.33 倍的 FastQueryEscape的更多相关文章

  1. runnable:在线IDE+代码片段分享

    在我之前的博客20个最好的在线IDE中列举过很多在线IDE,可以很方便的在云端执行代码,这样在你手头没有编译器时想试个小程序会非常有用. 今天介绍的这个网站runnable把在线IDE和代码片段结合了 ...

  2. 很棒的jQuery代码片段分享

    jQuery实现的内链接平滑滚动 不需要使用太复杂的插件,只要使用下载这段代码即可实现基于内部链接的平滑滚动 $('a[href^="#"]').bind('click.smoot ...

  3. 三行Python代码,让你的数据处理脚本快别人4倍

    Python是一门非常适合处理数据和自动化完成重复性工作的编程语言,我们在用数据训练机器学习模型之前,通常都需要对数据进行预处理,而Python就非常适合完成这项工作,比如需要重新调整几十万张图像的尺 ...

  4. 10 个实用的 jQuery 表单操作代码片段

    jQuery 绝对是一个伟大的开源JavaScript类库,是帮助我们快速和高效开发前端应用的利器.可能大家在日常的开发过程中常常会处理表单相关的 JavaScript,在今天这篇代码片段分享文章中, ...

  5. 10个超棒jQuery表单操作代码片段

    jQuery绝对是一个伟大的开源javascript类库,是帮助我们快速和高效开发前端应用的利器.可能大家在日常的开发过程中常常会处理表单相关的javascript,在今天这篇代码片段分享文章中,这里 ...

  6. 不可错过的10个超棒jQuery表单操作代码片段

    jQuery 绝对是一个伟大的开源javascript类库,是帮助我们快速和高效开发前端应用的利器.可能大家在日常的开发过程中常常会处理表单相关的 javascript,在今天这篇代码片段分享文章中, ...

  7. 微信小程序代码片段

    微信小程序代码片段是一种可分享的小项目,可用于分享小程序和小游戏的开发经验.展示组件和 API 的使用.复现开发问题等等.分享代码片段会得到一个链接,所有拥有此分享链接的人可以在工具中导入此代码片段. ...

  8. 经验分享:10个简单实用的 jQuery 代码片段

    尽管各种 JavaScirpt 框架和库层出不穷,jQuery 仍然是 Web 前端开发中最常用的工具库.今天,向大家分享我觉得在网站开发中10个简单实用的 jQuery 代码片段. 您可能感兴趣的相 ...

  9. 分享10个超实用的jQuery代码片段

    来源:GBin1.com jQuery以其强大的功能和简单的使用成为了前端开发者最喜欢的JS类库,在这里我们分享一组实用的jQuery代码片段,希望大家喜欢! jQuery平滑回到顶端效果 $(doc ...

  10. web 分享代码片段

    <div class="bshare-custom icon-medium-plus"><a title="分享到QQ空间" class=&q ...

随机推荐

  1. 华为云GaussDB新产品特性亮相DTC2021,重磅新品开源预告

    摘要:华为云数据库产品部CTO庄乾锋携3位GaussDB技术专家在DTC2021大会上分享了产品最新技术.优秀实践案例,以及透露了重大新品即将开源,以数据驱动业务发展,为企业数字化转型持续注入新动力. ...

  2. 火山引擎 DataTester 推出可视化数据集成方案

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着数字化的长期演进,企业中往往存在多个运行在不同平台的数字系统,这些数据源彼此独立,数据跨系统间的交流.共享和融 ...

  3. .Net Core 开发框架,支持多版本的类库

    工具:Visual Studio 2019 1.新建一个 .NET Standard 类库. 2.填写项目名称 3.编辑项目文件 可以看到当前类库默认为 netstandard2.0,而此时其xml标 ...

  4. 微服务网关 —— SpringCloud Netflix Zuul

    概述 Spring Cloud Zuul 是 Spring Cloud Netflix 子项目的核心组件之一,可以作为微服务架构中的 API 网关使用,有以下用途: 鉴权:对于访问每个服务的请求进行鉴 ...

  5. 使用 BLIP-2 零样本“图生文”

    本文将介绍来自 Salesforce 研究院的 BLIP-2 模型,它支持一整套最先进的视觉语言模型,且已集成入 Transformers. 我们将向你展示如何将其用于图像字幕生成.有提示图像字幕生成 ...

  6. 流媒体传输协议之 RTMP

    作者:逸殊 审核:泰一 简介 RTMP 在可靠流式传输(TCP)的基础上提供了双向的消息多路复用服务,在通讯双方之间传输与时间相关的并行流数据,如音频,视频和数据消息.协议实现方通常为不同的消息类型指 ...

  7. 2021InfoComm|钉钉会议 Rooms 的 "全场景" 智能化解决方案

    InfoComm China 是亚太地区规模盛大的专业视听和集成体验解决方案商贸展会,提供前沿革新的产品和一系列高价值的技术展示. 在疫情期间,钉钉音视频支持了全国人民在线办公.在家上课,单日在线会议 ...

  8. AcWing第四场周赛

    比赛链接:Here AcWing 3694. A还是B 签到题 void solve() { int n; string s; cin >> n >> s; int t = c ...

  9. 十一、docker的容器互联

    系列导航 一.docker入门(概念) 二.docker的安装和镜像管理 三.docker容器的常用命令 四.容器的网络访问 五.容器端口转发 六.docker数据卷 七.手动制作docker镜像 八 ...

  10. spring启动流程 (5) Autowired原理

    构造方法参数Autowire BeanClass可以在构造方法上标注@Autowired注解,Spring在创建Bean实例时将自动为其注入依赖参数 Spring会优先使用标注@Autowired注解 ...