Ruby 2.2:解密字符串key性能提升
Posted ruby程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ruby 2.2:解密字符串key性能提升相关的知识,希望对你有一定的参考价值。
每个人都希望他们的程序跑的更快而且使用的内存更少,但是不修改源代码往往达不到这个要求,这篇文章将介绍ruby2.2.0版本下在hash的优化,要向充分的理解这些优化,就必须知道现在存在的问题。
在Ruby2.1版本之前,如果我们像这样写代码:
Ruby会自动的分配内存给字符串"access_string",以便使用这个字符串的key来查找这个实体,简单的说当你创建一个hash的时候,Ruby必须每次都分别空间给这个字符串。
当这段程序调用的时候,"foo"字符串每次都会分配内存, 这看起来不是什么大问题,但是如果你在使用Rack创建一个字符串为key的hash时,并且每次请求都通过这个字符串来获取value那么你将会无意的创建很多无用的对象。
举个例子:在你的Rake项目中有15个文件这样使用,"PATH_INFO"被访问了36次:path = env["PATH_INFO"], 这样就会使我们的程序运行缓慢,并且消耗更多的内存空间。
Strings vs Symbols
通过benchmark来测试一下,使用symbol性能更高
require 'benchmark/ips'
STRING_HASH = { "foo" => "bar" }
SYMBOL_HASH = { :foo => "bar" }
Benchmark.ips do |x|
x.report("string") { STRING_HASH["foo"] }
x.report("symbol") { SYMBOL_HASH[:foo] }
end
Results:
------------------------------------------------
string 129.746k i/100ms
symbol 152.476k i/100ms
-------------------------------------------------
string 4.619M (± 5.0%) i/s - 23.095M
symbol 8.587M (± 5.4%) i/s - 42.846M
使用符号的性能是字符串的两倍,因为使用符号我们不需要再重新分配内存,但是在Ruby2.2版本后,加入了Symbol GC,会自动清理,如果你使用的2.2之前的版本,如果你在使用用户输入创建hash,那么你的系统就存在被DOS攻击的危险。
Ruby2.2增加了symbol GC,这种情况在2.2版本得到了有效的控制,如果已经定义了一个字符串,然后在这个字符串上调用to_sym方法会更耗时。
如果Rack项目中使用了大量的字符串作为key,而的调整api使用符号又不是很容易的情况下,如果提高性能呢?告诉Ruby不要再重新分配内存了,使用String.freeze。freeze意味着字符串不会被修改。
require 'benchmark/ips'
HASH = { "PATH_INFO" => "bar" }
Benchmark.ips do |x|
x.report("freeze") { HASH["PATH_INFO".freeze] }
x.report("normal") { HASH["PATH_INFO"] }
end
Result:
------------------------------------------------
freeze 144.130k i/100ms
normal 127.572k i/100ms
-------------------------------------------------
freeze 7.326M (± 3.2%) i/s - 36.609M
normal 4.566M (± 4.1%) i/s - 22.835M
使用String#freeze方法明显更快一点,Ruby2.2字符串hash性能提升, 虽然String#freeze漂亮的解决了我们的问题,但是还不够Ruby-esque,为什么Ruby不能帮我们做呢?其实Ruby可以!在Ruby2.2后,它会自动的帮我们做这个处理,帮助我们提高性能。
-------------------------------------------------
string 116.342k i/100ms
symbol 116.099k i/100ms
-------------------------------------------------
string 6.649M (±10.6%) i/s - 32.808M
symbol 7.785M (± 9.9%) i/s - 38.545M
我非常喜欢这个特性,它让我们更专注于业务,VM会帮助我们来处理这种情况,而不需要我们做任何别的处理就能享受它给
我们带来的性能提升。
以上是关于Ruby 2.2:解密字符串key性能提升的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch腾讯万亿级 Elasticsearch 内存效率提升解密 源码级别 性能优化
GaussDB(DWS) NOT IN优化技术解密:排他分析场景400倍性能提升
采用alluxio提升MR job和Spark job性能的注意点