2013-03-07 146 views
3

考虑以下情形从缓存弦作曲JSON,我有想象中的那么我需要把一个数组,然后将其转换成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

我用JSON.dump检查了我之前的回答,但没有奏效 - 对不起! – 2013-03-07 20:13:38

回答

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字符串的事
0

编辑

我以前的回答完全错过了这个问题(我们对此深感抱歉)的性能方面,所以这是我的发现。也许它可以帮助你一点。

很明显,在这些使用yajl-ruby的情况下,这是对yarjl库的绑定,似乎可以在转换时提高性能。举例来说,我在这里生成一个散列与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) 

Consistenly IM减半转化为JSON的任务的时间。希望能帮助到你!

+0

解析缓存的json字符串只是为了再次将其转换为json?我在这里谈论性能优化。 – teamon 2013-03-07 21:04:36

+0

@teamon对不起,我更新了我的答案。希望更有帮助。 – fmendez 2013-03-07 21:39:24

+0

谢谢你的努力,但不,它根本没有帮助。我已经使用yajl(我已经测试了所有可用的json库for ruby​​),让事情更快的唯一方法是将散列缓存为渲染的json。我已经在缓存哈希,但这还不够。 – teamon 2013-03-07 21:47:31