首页 > 其他分享 >【代码片段分享】比 url.QueryEscape 快 7.33 倍的 FastQueryEscape

【代码片段分享】比 url.QueryEscape 快 7.33 倍的 FastQueryEscape

时间:2023-06-11 16:55:23浏览次数:39  
标签:7.33 string url unsafe FastQueryEscape QueryEscape byte buf

作者:张富春(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")
	}
}

标签:7.33,string,url,unsafe,FastQueryEscape,QueryEscape,byte,buf
From: https://www.cnblogs.com/ahfuzhang/p/17473178.html

相关文章

  • lua对url字符进行编解码
      localfunctionurlEncode(s)s=string.gsub(s,"([^%w%.%-])",function(c)returnstring.format("%%%02X",string.byte(c))end)returnstring.gsub(s,"","+")endlocalfunctionurlDecode(s)s=strin......
  • URL转义解码的网址
    比如邮箱解码:  网址: http://www.wetools.com/url-encode   点击解码完成: ......
  • CTFSHOW PARSE_URL
    第一关parse_url(string$url,int$component=-1):int|string|array|null|false本函数解析URL并返回关联数组,包含在URL中出现的各种组成部分。数组的元素值不会URL解码。本函数不是用来验证给定URL的有效性的,只是将其分解为下面列出的部分。也会接受不完整或无效......
  • 取公共的APIURL​
    取公共的APIURL​项目新增common目录,里面有个common.js constcommon={getapiurl(){ varapiurl=uni.getStorageSync("apiurl"); if(apiurl==undefined||apiurl==''){ apiurl="http://product.niunan.net"; uni.setStorageSync......
  • driverClassName、url
    MySQL的链接中间件mysql-connector-java.jar的版本不同,链接驱动类名也有所不同,具体如下:driverClassName:com.mysql.jdbc.Driver#是mysql-connector-java5中的driverClassName:com.mysql.cj.jdbc.Driver#是mysql-connector-java6及之后的更高版本中的url:jdbc:mys......
  • 解析url
    //parseurl解析urlcc++代码rfc2068#include<stdio.h>#include<string.h>#include<stdlib.h>//解析url,作为示例,很多情况没考虑,比如说user,pass之类的intparse_url(char*url,char**serverstrp,int*portp,char**pathstrp){charbuf[256];......
  • url中的jsessionid解释
    url中的jsessionid解释(1)这是一个保险措施因为Session默认是需要Cookie支持的但有些客户浏览器是关闭Cookie的这个时候就需要在URL中指定服务器上的session标识,也就是5F4771183629C9834F8382E23BE13C4C用一个方法(忘了方法的名字)处理URL串就可以得到这个东西这个方法......
  • Windows证书管理器 && SSL certification && WSL-Docker: curl: (60) SSL certificat
    深入浅出certmgr——Windows证书管理器https://www.fke6.com/html/91605.html计算机安全是当前社会的一个重要议题,证书是一种重要的安全机制,负责证明数据、软件或者人的身份和信誉。certmgr(即“证书管理器”)是Windows中专门用于证书管理的工具。本文将从多个方面对certmgr进行深......
  • 深入了解 HTTP 请求和响应、表单处理和验证、URL 路由和重定向、Web 服务和 API 开发,
    在Web开发中,了解HTTP请求和响应、表单处理和验证、URL路由和重定向、Web服务和API开发,以及PHP模板引擎和视图是非常重要的。本文将深入探讨这些概念,并提供相关的代码示例。1.HTTP请求和响应HTTP(超文本传输协议)是用于在客户端和服务器之间传输数据的协议。在Web开发中......
  • 报错 ImportError: urllib3 v2.0 only
     麻烦您到服务器命令行执行下面命令修复下btpipinstall-Irequests==2.27bt1  您好,该问题是requests模块库与OpenSSL模块问题导致的,您那边可到服务器命令行下使用下面命令尝试解决。修复requests模块命令:btpipinstallrequests-U  解决问题帖子......