是不是现代计算机足以处理字符串而不需要使用符号(在Ruby中)

时间:2009-03-17 23:41:26

标签: ruby performance string symbols

我读过的关于Ruby符号的每一篇文章都谈到了符号在字符串上的效率。但是,这不是20世纪70年代。我的电脑可以处理一些额外的垃圾收集。我错了吗?我有最新最好的奔腾双核处理器和4演出的RAM。我认为应该足以处理一些字符串。

5 个答案:

答案 0 :(得分:17)

你的计算机很可能能够处理“一点点额外的垃圾收集”,但是当这个“一点点”发生在一个运行数百万次的内循环中呢?什么时候它在内存有限的嵌入式系统上运行?

有很多地方可以随便使用字符串,但有些地方你不能。这一切都取决于具体情况。

答案 1 :(得分:13)

确实,出于记忆原因,你不需要令牌非常糟糕。你的计算机无疑可以处理各种粗糙的字符串处理。

但是,除了速度更快之外,令牌还有额外的优势(尤其是上下文着色)在视觉上尖叫:看看我,我是一个关键值对的关键。这对我来说是一个很好的理由。

还有其他原因......而且很多因素的性能提升可能比你意识到的要多,特别是做比较之类的事情。

比较两个ruby符号时,解释器只是比较两个对象地址。比较两个字符串时,解释器必须一次比较一个字符。如果你做了很多这样的计算,那么这种计算就会加起来。

虽然符号有自己的性能问题但它们从不被垃圾收集。

值得一读这篇文章: http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol

答案 2 :(得分:2)

很好的是,符号保证是唯一的 - 可以有一些你不会从String中获得的好效果(例如它们的地址总是完全相同)。

另外他们有不同的含义你想在不同的领域使用它们,但是ruby对这种东西并不是太严格,所以我能理解你的问题。

答案 3 :(得分:2)

这是差异的真正原因:字符串永远不会相同。即使内容相同,字符串的每个实例都是一个单独的对象。对字符串的大多数操作都会生成 new 字符串对象。请考虑以下事项:

a = 'zowie'
b = 'zowie'
a == b         #=> true

从表面上看,很容易声称ab是相同的。大多数常识操作都会按照您的预期运行。但是:

a.object_id    #=> 2152589920 (when I ran this in irb)
b.object_id    #=> 2152572980
a.equal?(b)    #=> false

他们看起来相同,但他们是不同的对象。 Ruby必须分配两次内存,两次执行String#initialize方法,等等。它们在内存中占用两个独立的位置。嘿!当您尝试修改它们时会变得更加有趣:

a += ''        #=> 'zowie'
a.object_id    #=> 2151845240

这里我们将 nothing 添加到a并保留内容完全相同 - 但Ruby不知道这一点。它仍然分配一个全新的String对象,将变量a重新分配给它,旧的String对象坐在那里等待最终的垃圾收集。哦,空的''字符串也会获得一个临时的String对象,该对象仅在该行代码的持续时间内分配。试试吧,看看:

''.object_id   #=> 2152710260
''.object_id   #=> 2152694840
''.object_id   #=> 2152681980

在光滑的多千兆赫处理器上,这些对象分配是否快速?当然可以。他们会嚼掉你4 GB内存的大部分吗?不,他们不会。但这样做了几百万次,它开始加起来。大多数应用程序在整个地方使用临时字符串,并且您的代码可能在方法和循环中充满了字符串文字。每个字符串文字等都会分配一个新的String对象,每次该代码行都会运行。真正的问题甚至不是记忆浪费;这是垃圾收集过于频繁触发而你的应用程序开始挂起所浪费的时间。

相反,请看一下符号:

a = :zowie
b = :zowie
a.object_id    #=> 456488
b.object_id    #=> 456488
a == b         #=> true
a.equal?(b)    #=> true

一旦符号:zowie生成,它就永远不会生成另一个符号。每次引用给定的符号时,都指的是同一个对象。没有时间或内存浪费在新的分配上。如果你对它们过于疯狂,这也可能是一个缺点 - 它们从不垃圾收集,所以如果你开始从用户输入动态创建无数符号,你就冒着无休止的内存泄漏的风险。但是对于代码中的简单文字,例如常量值或散列键,它们只是完美无缺。

这有帮助吗?这不是你的应用程序曾经做过什么。这是关于它做了数百万次的事情。

答案 4 :(得分:1)

要输入的字符少一个。这就是我需要将它们用于字符串以用于散列键等的所有理由。