问题标签 [string-interning]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 如何避免内部对象的慢等于?
我正在创建一些相当大的对象,其中许多是重复的。所以我考虑Interner
为他们使用番石榴,并且总是只使用实习对象(即,每个对象在创建后立即被实习)。
我突然想到equals
这些对象相当慢(并且经常被使用)而且我实际上从来不需要它,就像a.equals(b)
实习a == b
之后一样。不幸的是,它Interner
本身使用equals
,所以我必须覆盖它以供一次性使用。
我想知道是否有一种简单的方法可以让我吃掉它?
免责声明:我知道万恶之源,我不确定这个地方的优化是否值得。但是,如果上述问题有一个很好的解决方案,我很感兴趣。
java - Java 中的 == 运算符
以下在 Java 中是正确的
为什么?这两个Strings是两个不同的对象,它们不应该具有相同的对象标识吗?
c# - 读取字符串实习生池的内容
我想枚举字符串实习生池中的字符串。
也就是说,我想得到这样的所有实例的s
列表string
:
有谁知道这是否可能?
java - java中的实习生()是什么?
实习生()的目的是什么?
java - String.intern() 真的能提高性能吗?
我做了一些调查以了解该String.intern()
方法是如何在 java 中实现的。
我查看了 Open JDK 6 中实习生池的 C++ 实现,在那里我看到了一个简单的HashSet
. 对我来说,这意味着当有人尝试实习时,String
应该完成以下步骤:
- 查找与给定关联的哈希码
String
- 找到合适的桶
- 将给定的字符串与桶中的所有其他字符串进行比较。在此步骤之前,桶中可能有 0 个字符串、一个字符串或很多字符串。因此,如果给定的字符串之前已放入桶中,我们将至少得到一个比较(这是最好的情况。当然可能有很多冲突,现在桶中还有许多其他字符串)
- 如果在桶中找到了字符串,那么它应该通过
intern()
方法返回 - 如果在桶中没有找到该字符串,则应将其放入桶中并通过
intern()
方法返回
所以很多人说那str1.intern() == str2.intern()
会比str1.equals(str2)
.
但我看不出它应该更快的原因。
正如我所看到的,如果我们总是有两个字符串在方法str1.equals(str2)
中逐字符比较。String.equals()
在这种情况下str1.intern() == str2.intern()
,我们需要进行多少次比较或将字符串放入池中/从池中取出(对,可能是很多比较,它们也是简单的逐字符比较)?
因此,str1.intern() == str2.intern()
即使我们使用==
比较字符串,我们也会有许多额外的操作,例如前面描述的比较。
当我理解它时,我决定进行一些基准测试。
第一个结果告诉我,str1.intern() == str2.intern()
它比str1.equals(str2)
.
这种行为是由于String.intern()
方法是本机的,因此不应每次都对其进行解释,并且String.equals()
是 java 方法。
因此,我决定使用-Xcomp
选项让 JVM 在启动时编译所有代码。
在那之后等于展示了比实习生更好的速度。
我在 Java 6 和 7 上对其进行了测试。
所以我的问题是你有没有见过在实习提高字符串比较速度时的情况?我是的,怎么可能?
或者也许intern()
只能帮助节省更多的可用内存?
python - 实习多头
如果您有很多相同字符串的副本浮动, Python 的intern
函数可以通过将它们全部替换为对单个对象的引用来节省内存。
我有类似的情况,除了我处理的是long
s 而不是字符串。
有没有办法用 s 做类似的事情long
?
java - 在编译时或运行时什么时候完成实习?代码中出现这种行为的原因是什么?BlueJ 中的问题?
的
string
值为 12 。并且 'string_input' 存储
string
在代码中声明和初始化的输入数字,而 string_input 由用户在运行时输入
情况1
当我们输入“12”时它返回true
案例2
现在当我们输入“012”..它返回false
为什么会这样???:/
c# - 使用字符串实习来减少网络客户端的内存使用
我有一个网络客户端,它处理来自服务器的数据。
数据作为一系列消息发送,它们本身是键/值集合,在概念上类似于 HTTP 标头(除了没有“消息体”),这是一个典型的单向消息(行分隔\r\n
):
我的协议客户端通过使用andNetworkStream
逐个字符读取,并使用状态机解析器和实例来填充实例。然后将这些 Dictionary 实例保存到内存结构中以供进一步处理,它们的使用寿命通常约为 10 分钟。StreamReader
while( (nc = rdr.Read()) != -1 )
StringBuilder
Dictionary<String,String>
我的客户每小时会收到数千条这样的消息,并且客户端进程是持久的——这是一个问题,因为我的客户端进程经常增长到从这些String
实例中消耗超过 2GB 的内存——我使用 windbg 来查看所有内存的去向. 这是一个问题,因为代码在只有 3.5GB 内存的 Azure VM 上运行。我看不出为什么我的程序最多应该消耗超过几百 MB 的 RAM。通常我会照看虚拟机并观察我的进程的内存消耗随着时间的推移,它会稳步增长到大约 2GB,然后随着 GC 的收集运行突然下降到大约 100MB,然后它会再次增长。GC 运行之间的时间可能会有所不同,根本无法预测。
因为这些字符串中有很多是相同的(例如键Response
,Status
等)以及已知值OK
,Fail
所以我可以使用字符串实习来减少使用,如下所示:
问题是我看到了额外优化的空间:sb.ToString()
将分配一个新的字符串实例,它将用于实习,其次:实习字符串在 appdomain 的生命周期内持续存在,不幸的是有些键不会看到重新-use 并且实际上会浪费内存,例如Foo123
在我的协议示例中。
我认为的一种解决方案是不使用字符串实习,而是有一个包含static readonly
字符串字段的类,这些字段是已知的键,然后使用普通的非实习字符串——这最终会被 GC 处理,因此不会冒着填满字符串实习池的风险一次性字符串。然后我会将StringBuilder
实例与这些已知字符串进行比较,如果是,则使用它们而不是调用sb.ToString()
从而跳过另一个字符串分配。
但是,如果我确实选择实习生每个字符串,实习生池将继续增长,不幸的是.NET似乎没有.Chlorinate()
字符串池的方法,有没有办法从实习生池中删除一次性字符串如果我继续这种String.Intern
方法,还是我最好使用我自己的静态只读字符串实例?
c# - .NET 是否为每个程序集创建一个字符串实习生池?
我有一种情况,我会遇到很多重复的字符串,这些字符串会在内存中持续很长时间。我想使用String.Intern
但我不想侵入任何潜在的应用程序资源,因为我的项目是一个库。这是如何运作的?
javascript - 为什么 Javascript ===/== 字符串相等有时具有恒定时间复杂度,有时具有线性时间复杂度?
在我发现常见/最新的 Javascript 实现使用字符串实习来提高性能(常见的 JavaScript 实现是否使用字符串实习?)之后,我认为===
字符串会获得恒定的 O(1) 时间。所以我对这个问题给出了错误的答案:
由于根据该问题的 OP 它是 O(N),因此将字符串输入加倍会使相等所需的时间加倍。他没有提供任何 jsPerf,因此需要进行更多调查,
所以我使用字符串实习的场景是:
var str1 = "stringwithmillionchars"; //stored in address 51242
var str2 = "stringwithmillionchars"; //stored in address 12313
一旦假设在内存的地址 201012 中,“stringwithmillionchars”将被存储,并且 str1 和 str2 都将“指向”该地址 201012。然后可以使用某种散列来确定该地址以映射到内存中的特定位置。
所以做的时候
"stringwithmillionchars" === "stringwithmillionchars"
看起来像
getContentOfAddress(51242)===getContentOfAddress(12313)
或者201012 === 201012
这将花费 O(1)/恒定时间
JSPerfs/性能更新:
即使字符串长 16 倍,JSPerf 似乎也显示恒定时间?请看一看:
http://jsperf.com/eqauility-is-constant-time
上面的字符串可能太小了:这可能显示线性时间(感谢 sergioFC)字符串是用循环构建的。我尝试了没有功能 - 仍然是线性时间/我改变了一点http://jsfiddle.net/f8yf3c7d/3/。
根据https://www.dropbox.com/s/8ty3hev1b109qjj/compare.html?dl=0(sergioFC 制作的 12MB 文件),当你有一个字符串并且无论 t1 有多大,你已经用引号分配了值和 t2 是(例如 5930496 个字符),它需要 0-1 毫秒/即时时间。
似乎当您使用 for 循环或函数构建字符串时,该字符串不会被保留。因此,只有当您直接分配带有引号的字符串时才会发生实习var str = "test";