【学到一个新名词】String interning(字符串驻留/字符串内部化)
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
在阅读 VictoriaMetrics v1.95.1 的命令行手册的时候,发现这样一段:
-internStringCacheExpireDuration duration
The expiry duration for caches for interned strings. See https://en.wikipedia.org/wiki/String_interning . See also -internStringMaxLen and -internStringDisableCache (default 6m0s)
什么是 String interning 呢?我通过了 wiki 链接学习了一下。
并且,我还找到了一个使用 String interning 技术的 golang 项目:https://github.com/josharian/intern . 作者还写了 blog: Interning strings in Go 来进一步介绍细节。
String interning 可以翻译为 字符串驻留 或者 字符串内部化。这个技巧用于节约频繁出现的字符串的空间占用,还可以用于频繁出现的字符串的比较的加速。
它的处理思路如下:
- 首先有一个全局的线程安全的键值对的字符串池;
类似于: map[string]string
然后把出现频率超级高的字符串存储在其中。
当出现新的字符串的时候,要先去字符串池中匹配。
匹配到以后,程序就可以引用字符串池中的对象,而把当前引用的对象释放掉。
当存在大量的这样内容相同的字符串的时候,这样做无疑是可以节省空间的。
在这样的场景下,相当于时间换空间。当字符串都来自字符串池,且需要频繁比较的时候,直接比较指针就可以确定是否是同一个字符串,而无需逐个字符比较。
在这样的场景下,相当于空间换时间。
让我们再看看那个简单的 golang 实现的字符串内部化的源码:
see: https://github.com/josharian/intern/blob/master/intern.go
package intern
import "sync"
var (
pool sync.Pool = sync.Pool{ // 作者想用 sync.Pool 来解决不引用时候的释放问题。但是并发环境下可能导致分配了多个键值对的字符串池。
New: func() interface{} { // sync.Pool 能够在并发环境下工作,不管怎么说,并发情况下使用不会出错。
return make(map[string]string)
},
}
)
// String returns s, interned.
func String(s string) string {
m := pool.Get().(map[string]string)
c, ok := m[s] // 这里要经过 1.计算字符串 hashcode; 2.hash 查找; 3.字符串内容比较。时间换空间的成本还是挺高的。
if ok {
pool.Put(m)
return c // 如果字符串池中存在,就置换为字符串池中的对象
}
m[s] = s // 这里不会发生并发问题
pool.Put(m)
return s
}
// Bytes returns b converted to a string, interned.
func Bytes(b []byte) string {
m := pool.Get().(map[string]string)
c, ok := m[string(b)] // string(b) 这里有个隐含的知识点:这种情况下编译器不会分配新的字符串对象。
if ok {
pool.Put(m)
return c
}
s := string(b)
m[s] = s
pool.Put(m)
return s
}
// todo: 这里还缺乏一个内容:当字符串都来自字符串池的时候,可以提供按照指针比较的方法
// 类似于:
// isSmae := &str1==&str2 || str1==str2
看完了源码,这个字符串内部化似乎也没有很复杂很高深。或许某个存在大量重复字符串的场景中,我们很能用上这个技术。
Have fun.
【学到一个新名词】String interning(字符串驻留/字符串内部化)的更多相关文章
- 什么是string interning(字符串驻留)以及python中字符串的intern机制
Incomputer science, string interning is a method of storing only onecopy of each distinct string val ...
- Java中的字符串驻留(String Interning)
1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ne ...
- String特性之 “字符串驻留池”
1. 字符串驻留池,就是一块与堆区并行的存放字符串对象的内存区,JVM的驻留池机制规定: 在池中创建一个String对象,第二行会先在池中寻找是否有值与"abc"相同的String ...
- [你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考
发布日期:2008.8.27 作者:Anytao © 2008 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 走钢丝的人,在刺激中体验快感.带着问题思考,在问题 ...
- 深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!
英文:https://arpitbhayani.me/blogs/string-interning 作者:arpit 译者:豌豆花下猫("Python猫"公众号作者) 声明:本翻译 ...
- JAVA 字符串驻留池
一切从String str = new String("abc")说起... 这行代码形式上很简单,其实很复杂.有一个常见的Java笔试题就是问上面这行代码创建了几个Stri ...
- .Net字符串驻留池
在.Net中,对于相同的字符串,.Net会将它们指向同一个地址,它们是相同的实例..Net中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.Net实际上是新创建一个字符串,而将变量 ...
- C#中字符串驻留技术
转自:http://www.cnblogs.com/Charles2008/archive/2009/04/12/1434115.html MSDN概念:公共语言运行库通过维护一个表来存放字符串,该表 ...
- C# 字符串驻留池
在.Net中,对于相同的字符串,.Net会将它们指向同一个地址,它们是相同的实例..Net中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.Net实际上是新创建一个字符串,而将变量 ...
- Java中的字符串驻留
转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = “hello” + “world”;被 ...
随机推荐
- DHorse v1.3.0 发布,基于k8s的发布平台
综述 DHorse是一个简单易用.以应用为中心的云原生DevOps系统,具有持续集成.持续部署.微服务治理等功能,无需安装依赖Docker.Maven.Node等环境即可发布Java.Vue.Reac ...
- 王道oj/problem23
网址:oj.lgwenda.problem/23 代码: #define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include<stri ...
- WPF 入门笔记 - 07 - MVVM示例
滴咚,大家好久不见.好就没写东西了,鸽着鸽着就无了... 回到正题,上篇文章说完命令提了一嘴MVVM模式直接就上MVVMLight这些程序的框架了,虽然也没说多少,但还是有点不好过渡,这篇对MVVM做 ...
- ctfshow--web入门--文件上传
ctfshow--web入门--文件上传 web151(前端校验) 题目中提示前端检验不可靠,应该对前端检验进行绕过 检查前端代码进行修改,使php文件可以通过前端校验,成功上传后进行命令执行,找到f ...
- [ABC128D] equeue
2023-01-14 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 暴力,贪心 解题思路 由题意可以得出,数据只有 \(n \leq 50,k ...
- 关于XXLJOB集群模式下调度失败的问题
xxljob在集群模式下调度高频任务时,有时会出现调度失败的问题,具体报错如下: java.io.EOFException: HttpConnectionOverHTTP@6be8bf0c(l:/10 ...
- 文心一言 VS 讯飞星火 VS chatgpt (96)-- 算法导论9.3 1题
一.用go语言,在算法 SELECT 中,输人元素被分为每组 5 个元素.如果它们被分为每组 7个元素,该算法仍然会是线性时间吗?证明:如果分成每组 3 个元素,SELECT 的运行时间不是线性的. ...
- git升级编译安装
一.删除旧版本git 方法一. yum remove git -y (centos环境) apt-get remove git -y (Ubuntu环境) 方法二. which git [root@p ...
- PowerDotNet平台化软件架构设计与实现系列(16):财务平台
不同行业基本都会有自己独特的业务,甚至同行的不同企业之间的业务逻辑也会相差千里,只有最大程度抽象出通用性.标准性和普适性的系统才能够成为平台系统,平台系统开发的成本和难度可想而知. 个人深度参与或独立 ...
- frida动态插桩初探
前言 近期碰到了分析app的需求,就学习了一下 frida的动态插桩技术.frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等.frida分为两部分,服务端 ...
