【发布时间】:2011-02-23 23:49:04
【问题描述】:
如果使用 Marshal.dump 将其写入文件,我有一个大约 10 兆字节的 Ruby 哈希。 gzip 压缩后大约为 500 KB。
在 ruby 中迭代和更改此哈希非常快(毫秒的分数)。即使复制它也非常快。
问题是我需要在 Ruby on Rails 进程之间共享此哈希中的数据。为了使用 Rails 缓存(file_store 或 memcached)执行此操作,我需要首先 Marshal.dump 文件,但这会在序列化文件时产生 1000 毫秒的延迟,在序列化文件时会产生 400 毫秒的延迟。
理想情况下,我希望能够在 100 毫秒内从每个进程中保存和加载此哈希。
一个想法是产生一个新的 Ruby 进程来保存这个哈希,它为其他进程提供一个 API 来修改或处理其中的数据,但我想避免这样做,除非我确定没有其他进程快速共享此对象的方法。
有没有一种方法可以更直接地在进程之间共享此哈希,而无需对其进行序列化或反序列化?
这是我用来生成类似于我正在使用的哈希的代码:
@a = []
0.upto(500) do |r|
@a[r] = []
0.upto(10_000) do |c|
if rand(10) == 0
@a[r][c] = 1 # 10% chance of being 1
else
@a[r][c] = 0
end
end
end
@c = Marshal.dump(@a) # 1000 milliseconds
Marshal.load(@c) # 400 milliseconds
更新:
由于我最初的问题没有收到很多回复,我假设没有像我希望的那样简单的解决方案。
目前我正在考虑两种选择:
- 创建一个 Sinatra 应用程序来存储这个哈希值,并使用一个 API 来修改/访问它。
- 创建一个 C 应用程序以执行与 #1 相同的操作,但要快得多。
我的问题范围扩大了,以至于哈希可能比我原来的例子大。所以#2可能是必要的。但我不知道从哪里开始编写公开适当 API 的 C 应用程序。
如何最好地实施 #1 或 #2 的良好演练可能会获得最佳答案。
更新 2
我最终将它实现为一个用 Ruby 1.9 编写的独立应用程序,它有一个 DRb 接口来与应用程序实例通信。我使用 Daemons gem 在 Web 服务器启动时生成 DRb 实例。启动时,DRb 应用程序从数据库加载必要的数据,然后与客户端通信以返回结果并保持最新状态。它现在在生产中运行得很好。感谢您的帮助!
【问题讨论】:
-
您能展示一下您使用哈希的方式吗?您展示了如何创建它,但是如何使用它?您提到了迭代、更改和复制,但您最常如何访问此哈希?
-
我正在使用哈希来计算用户之间的共性。每个值实际上代表一种兴趣,并设置为 0 或 1 来表示用户是否有兴趣。我需要能够非常快速地找到与用户最有共同兴趣的 20 个人。您可以在我对这个问题的回答中看到我正在使用的代码示例:stackoverflow.com/questions/2878429/…
标签: ruby-on-rails c ruby performance serialization