作者:张富春(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. target.closest妙用:UI(click/mousemove/drag/drop)事件元素查找捷径

    首先看下MDN:https://developer.mozilla.org/en-US/docs/Web/API/Element/closest 在jQuery时代,这个非常常见 $( documen ...

  2. Hive查看,删除分区

    查看所有分区 show partitions 表名; 删除一般会有两种方案 1.直接删除hdfs文件 亲测删除hdfs路径后 查看分区还是能看到此分区 可能会引起其他问题 此方法不建议 2. 使用删除 ...

  3. MySQL 创建存储过程注意项

    MySQL server version for the  right syntax to use near 'IF' MySQL server version for the right synta ...

  4. 只需 3 步,人人都能搭建自己的 chatgpt 微信机器人

    大家好,我是徐公,大厂 6 年经验,CSDN 博客专家.最近,ChatGpt 很火,身边的人都在讨论,会不会成为下一个风口,像前几年互联网一样,迎来井喷式的发展. 徐公我最近也是在密切关注,最近,在 ...

  5. 神经网络优化篇:详解RMSprop

    RMSprop 知道了动量(Momentum)可以加快梯度下降,还有一个叫做RMSprop的算法,全称是root mean square prop算法,它也可以加速梯度下降,来看看它是如何运作的. 回 ...

  6. 【3rd_Party】format() 处理一些常见的格式化解决方案

    fmt的痛与对format设计的思考 fmt:轻量高性能的C++格式化库 C++20 引入了新的 format() 函数,该函数以字符串形式返回参数的格式化表示.format() 使用 python ...

  7. 素数算法补充之"筛法"

    国庆中秋双节,就不写太长的文章了. 补充和复习一下以前没写的素数区间筛法算法吧 部分证明过程来自OI wiki 素数筛法 如果我们想要知道小于等于 \(n\) 有多少个素数呢? 一个自然的想法是我们对 ...

  8. SQL常用日期格式化转换与百分数转换

    目录 SQL将小数转为保留两位的百分数 常用的日期格式化 补充: 秒/毫秒转为持续时间 常用拼接方式: 本篇开启数据库在工作中常用到的格式转换与工具,欢迎大家评论留言 SQL将小数转为保留两位的百分数 ...

  9. Mycat 实现分库分表及读写分离

    本文为博主原创,未经允许不得转载: Mycat 官网: http://mycat.org.cn/ MyCat 权威指南 文档:http://www.mycat.org.cn/document/myca ...

  10. [kubernetes]服务健康检查

    前言 进程在运行,但是不代表应用是正常的,对此pod提供的探针可用来检测容器内的应用是否正常.k8s对pod的健康状态可以通过三类探针来检查:LivenessProbe.ReadinessProbe和 ...