考虑以下场景,我需要在数组中放入一些大哈希,然后将其转换为json:
hash1 = { ... big hash ... }
hash2 = { ... big hash ... }
hash3 = { ... big hash ... }
array = [hash1, hash2, hash3]
json = JSON.dump(array)
问题是从这些哈希生成json需要很长时间,所以我想缓存它。但是,我无法缓存整个数组,只能单独的项目。显然,将缓存的json字符串放在数组中会产生错误的结果:
hash1 = {:a => 1}
hash1json = JSON.dump(hash1)
array = [hash1json]
JSON.generate(array)
==> ["{\"a\":1}"]
虽然我需要
==> [{"a":1}]
我能想到的唯一方法是做这样的事情:
"[#{[hash1json].join(",")}]"
==> [{"a":1}]
这对于这个特定情况可能已经足够了,但如果想要缓存一些深层结构而不是简单数组,那将会更加困难。
答案 0 :(得分:2)
事实证明这实际上很简单:
class CachedJson
def initialize(str)
@str = str
end
def to_json
@str
end
end
puts Yajl::Encoder.encode(:data => [{:a => 1}, '{"b":2}'])
# => {"data":[{"a":1},"{\"b\":2}"]}
puts Yajl::Encoder.encode(:data => [{:a => 1}, CachedJson.new('{"b":2}')])
# => {"data":[{"a":1},{"b":2}]}
在引擎盖下yajl在每个对象上调用to_json
,并且此方法必须返回字符串,因此只需用CachedJson
对象包装缓存的json字符串
答案 1 :(得分:0)
修改强>
我之前的回答完全错过了问题的表现方面(对不起),所以这是我的发现。也许它可以帮到你一点点。
显然在这些情况下使用yajl-ruby
(绑定到C
yajl库)似乎可以在进行转换时提高性能。例如,我在这里生成一个带有10,000
条目的哈希:
require 'json'
require 'yajl'
require 'benchmark'
tmp = ""
10000.times do |i|
tmp += "\"#{i}\" => \"#{i}\", "
end
domains = eval("{#{tmp}}")
puts "JSON DUMP #{Benchmark.measure { JSON.dump(domains) }} "
puts "Yajl::Encoder #{Benchmark.measure { Yajl::Encoder.encode(domains)}}"
这些是结果:
JSON DUMP 0.010000 0.000000 0.010000 ( 0.007495)
Yajl::Encoder 0.000000 0.000000 0.000000 ( 0.003542)
始终将改造为json的任务的时间减半。希望它有所帮助!