mwa*_*way 10 ruby serialization ruby-on-rails marshalling deep-copy
我知道序列化一个对象(据我所知)是有效深度复制一个对象的唯一方法(只要它不像有状态那样IO),但是这种方法比另一种更有效吗?
例如,因为我正在使用Rails,我总是可以使用ActiveSupport::JSON,to_xml- 从我可以告诉编组的对象是最常被接受的方法之一.我希望编组可能是最有效的,因为它是一个Ruby内部,但我错过了什么?
编辑:请注意,它的实现是我已经涵盖的内容 - 我不想替换现有的浅拷贝方法(比如dup和clone),所以我最终可能会添加Object::deep_copy,其结果是上述方法中的任何一种(或者你有任何建议:)开销最小.
Eva*_*Pon 21
我想知道同样的事情,所以我对几种不同的技术进行了基准测试.我主要关注数组和哈希 - 我没有测试任何复杂的对象.也许不出所料,自定义深度克隆实现被证明是最快的.如果您正在寻找快速简便的实施方案,那么Marshal似乎就是您要走的路.
我还使用Rails 3.0.7对XML解决方案进行了基准测试,未在下面显示.只有1000次迭代,速度要慢很多,大约10秒钟(以下解决方案对于基准测试都运行10,000次).
关于我的JSON解决方案的两个注释.首先,我使用了C版本1.4.3.其次,它实际上不会100%工作,因为符号将转换为字符串.
这完全是用ruby 1.9.2p180运行的.
#!/usr/bin/env ruby
require 'benchmark'
require 'yaml'
require 'json/ext'
require 'msgpack'
def dc1(value)
Marshal.load(Marshal.dump(value))
end
def dc2(value)
YAML.load(YAML.dump(value))
end
def dc3(value)
JSON.load(JSON.dump(value))
end
def dc4(value)
if value.is_a?(Hash)
result = value.clone
value.each{|k, v| result[k] = dc4(v)}
result
elsif value.is_a?(Array)
result = value.clone
result.clear
value.each{|v| result << dc4(v)}
result
else
value
end
end
def dc5(value)
MessagePack.unpack(value.to_msgpack)
end
value = {'a' => {:x => [1, [nil, 'b'], {'a' => 1}]}, 'b' => ['z']}
Benchmark.bm do |x|
iterations = 10000
x.report {iterations.times {dc1(value)}}
x.report {iterations.times {dc2(value)}}
x.report {iterations.times {dc3(value)}}
x.report {iterations.times {dc4(value)}}
x.report {iterations.times {dc5(value)}}
end
Run Code Online (Sandbox Code Playgroud)
结果是:
user system total real
0.230000 0.000000 0.230000 ( 0.239257) (Marshal)
3.240000 0.030000 3.270000 ( 3.262255) (YAML)
0.590000 0.010000 0.600000 ( 0.601693) (JSON)
0.060000 0.000000 0.060000 ( 0.067661) (Custom)
0.090000 0.010000 0.100000 ( 0.097705) (MessagePack)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6665 次 |
| 最近记录: |