问题标签 [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.

0 投票
2 回答
499 浏览

java - 如何避免内部对象的慢等于?

我正在创建一些相当大的对象,其中许多是重复的。所以我考虑Interner为他们使用番石榴,并且总是只使用实习对象(即,每个对象在创建后立即被实习)。

我突然想到equals这些对象相当慢(并且经常被使用)而且我实际上从来不需要它,就像a.equals(b)实习a == b之后一样。不幸的是,它Interner本身使用equals,所以我必须覆盖它以供一次性使用。

我想知道是否有一种简单的方法可以让我吃掉它?


免责声明:我知道万恶之源,我不确定这个地方的优化是否值得。但是,如果上述问题有一个很好的解决方案,我很感兴趣。

0 投票
3 回答
145 浏览

java - Java 中的 == 运算符

以下在 Java 中是正确的

为什么?这两个Strings是两个不同的对象,它们不应该具有相同的对象标识吗?

0 投票
2 回答
489 浏览

c# - 读取字符串实习生池的内容

我想枚举字符串实习生池中的字符串。

也就是说,我想得到这样的所有实例的s列表string

有谁知道这是否可能?

0 投票
1 回答
440 浏览

java - java中的实习生()是什么?

实习生()的目的是什么?

0 投票
2 回答
893 浏览

java - String.intern() 真的能提高性能吗?

我做了一些调查以了解该String.intern()方法是如何在 java 中实现的。

我查看了 Open JDK 6 中实习生池的 C++ 实现,在那里我看到了一个简单的HashSet. 对我来说,这意味着当有人尝试实习时,String应该完成以下步骤:

  1. 查找与给定关联的哈希码String
  2. 找到合适的桶
  3. 将给定的字符串与桶中的所有其他字符串进行比较。在此步骤之前,桶中可能有 0 个字符串、一个字符串或很多字符串。因此,如果给定的字符串之前已放入桶中,我们将至少得到一个比较(这是最好的情况。当然可能有很多冲突,现在桶中还有许多其他字符串)
  4. 如果在桶中找到了字符串,那么它应该通过intern()方法返回
  5. 如果在桶中没有找到该字符串,则应将其放入桶中并通过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()只能帮助节省更多的可用内存?

0 投票
0 回答
31 浏览

python - 实习多头

如果您有很多相同字符串的副本浮动, Python 的intern函数可以通过将它们全部替换为对单个对象的引用来节省内存。

我有类似的情况,除了我处理的是longs 而不是字符串。

有没有办法用 s 做类似的事情long

0 投票
2 回答
293 浏览

java - 在编译时或运行时什么时候完成实习?代码中出现这种行为的原因是什么?BlueJ 中的问题?

输入是当你输入时,这将返回 true你什么时候进入string值为 12 。并且 'string_input' 存储 string在代码中声明和初始化的输入数字,而 string_input 由用户在运行时输入

情况1

当我们输入“12”时它返回true

案例2

现在当我们输入“012”..它返回false

为什么会这样???:/

0 投票
1 回答
615 浏览

c# - 使用字符串实习来减少网络客户端的内存使用

我有一个网络客户端,它处理来自服务器的数据。

数据作为一系列消息发送,它们本身是键/值集合,在概念上类似于 HTTP 标头(除了没有“消息体”),这是一个典型的单向消息(行分隔\r\n):

我的协议客户端通过使用andNetworkStream逐个字符读取,并使用状态机解析器和实例来填充实例。然后将这些 Dictionary 实例保存到内存结构中以供进一步处理,它们的使用寿命通常约为 10 分钟。StreamReaderwhile( (nc = rdr.Read()) != -1 )StringBuilderDictionary<String,String>

我的客户每小时会收到数千条这样的消息,并且客户端进程是持久的——这是一个问题,因为我的客户端进程经常增长到从这些String实例中消耗超过 2GB 的内存——我使用 windbg 来查看所有内存的去向. 这是一个问题,因为代码在只有 3.5GB 内存的 Azure VM 上运行。我看不出为什么我的程序最多应该消耗超过几百 MB 的 RAM。通常我会照看虚拟机并观察我的进程的内存消耗随着时间的推移,它会稳步增长到大约 2GB,然后随着 GC 的收集运行突然下降到大约 100MB,然后它会再次增长。GC 运行之间的时间可能会有所不同,根本无法预测。

因为这些字符串中有很多是相同的(例如键ResponseStatus等)以及已知值OKFail所以我可以使用字符串实习来减少使用,如下所示:

问题是我看到了额外优化的空间:sb.ToString()将分配一个新的字符串实例,它将用于实习,其次:实习字符串在 appdomain 的生命周期内持续存在,不幸的是有些键不会看到重新-use 并且实际上会浪费内存,例如Foo123在我的协议示例中。

我认为的一种解决方案是不使用字符串实习,而是有一个包含static readonly字符串字段的类,这些字段是已知的键,然后使用普通的非实习字符串——这最终会被 GC 处理,因此不会冒着填满字符串实习池的风险一次性字符串。然后我会将StringBuilder实例与这些已知字符串进行比较,如果是,则使用它们而不是调用sb.ToString()从而跳过另一个字符串分配。

但是,如果我确实选择实习生每个字符串,实习生池将继续增长,不幸的是.NET似乎没有.Chlorinate()字符串池的方法,有没有办法从实习生池中删除一次性字符串如果我继续这种String.Intern方法,还是我最好使用我自己的静态只读字符串实例?

0 投票
1 回答
1606 浏览

c# - .NET 是否为每个程序集创建一个字符串实习生池?

我有一种情况,我会遇到很多重复的字符串,这些字符串会在内存中持续很长时间。我想使用String.Intern但我不想侵入任何潜在的应用程序资源,因为我的项目是一个库。这是如何运作的?

0 投票
3 回答
2811 浏览

javascript - 为什么 Javascript ===/== 字符串相等有时具有恒定时间复杂度,有时具有线性时间复杂度?

在我发现常见/最新的 Javascript 实现使用字符串实习来提高性能(常见的 JavaScript 实现是否使用字符串实习?)之后,我认为===字符串会获得恒定的 O(1) 时间。所以我对这个问题给出了错误的答案:

JavaScript 字符串相等性能比较

由于根据该问题的 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";