fjs*_*js6 5 memory-management ruby-on-rails
我是一个在一个简单的Rails应用程序中工作的新手,它将文档(长字符串)从一种语言翻译成另一种语言.字典是一个术语表(一个用于查找和替换的字符串regexp,以及一个输出替换字符串的块).该表长达100万条记录.
每个请求都是一个想要翻译的文档.在第一个野蛮的力量方法中,我需要针对每个请求/文档运行整个字典.
由于字典每次都会运行(从第一个记录到最后一个),而不是用每个文档加载字典记录表,我认为最好将整个字典作为内存中的数组.
我知道它不是最有效的,但字典必须在这一点上运行.
1.-如果通过重组文档和字典无法获得效率(意味着无法创建较小的字典子集).什么是最好的设计方法?
2.-您是否了解我可以从中学到的类似项目?
3.-我应该在哪里学习如何在rails启动时将这么大的表加载到内存(缓存?)?
任何提出的问题的任何答案将不胜感激.非常感谢你!
我认为您的网络托管服务商不会对这样的解决方案感到满意。这个脚本
dict = {}
(0..1000_000).each do | num |
dict[/#{num}/] = "#{num}_subst"
end
Run Code Online (Sandbox Code Playgroud)
在我的 MBP 上消耗了 1 GB 的 RAM 来存储哈希表。另一种方法是将您的替换存储在内存缓存中,以便您(至少)可以跨计算机存储它们。
require 'rubygems'
require 'memcached'
@table = Memcached.new("localhost:11211")
retained_keys = (0..1000_000).each do | num |
stored_blob = Marshal.dump([/#{num}/, "#{num}_subst"])
@table.set("p#{num}", stored_blob)
end
Run Code Online (Sandbox Code Playgroud)
您将不得不担心如何保持密钥“热”,因为如果不需要它们,memcached 将使它们过期。
然而,对于您的情况,最好的方法非常简单 - 将替换写入一个文件(每个替换一行)并创建一个流过滤器,逐行读取文件,并从此文件中进行替换。您还可以通过映射工作来并行化它,例如,每个替换字母和替换标记。
但这应该让你开始:
require "base64"
File.open("./dict.marshal", "wb") do | file |
(0..1000_000).each do | num |
stored_blob = Base64.encode64(Marshal.dump([/#{num}/, "#{num}_subst"]))
file.puts(stored_blob)
end
end
puts "Table populated (should be a 35 meg file), now let's run substitutions"
File.open("./dict.marshal", "r") do | f |
until f.eof?
pattern, replacement = Marshal.load(Base64.decode64(f.gets))
end
end
puts "All replacements out"
Run Code Online (Sandbox Code Playgroud)
要填充文件并加载每个替换,我需要执行以下操作:
real 0m21.262s
user 0m19.100s
sys 0m0.502s
Run Code Online (Sandbox Code Playgroud)
只需从文件中加载正则表达式和字符串(全部一百万个,一块一块)
real 0m7.855s
user 0m7.645s
sys 0m0.105s
Run Code Online (Sandbox Code Playgroud)
因此,这是 7 秒的 IO 开销,但您不会丢失任何内存(并且还有巨大的改进空间) - RSIZE 约为 3 兆。如果您批量进行 IO,或者制作一个文件进行 10-50 次替换并将它们作为一个整体加载,您应该能够轻松地使其运行得更快。将文件放在 SSD 或 RAID 上,您就获胜了,但您可以保留 RAM。
| 归档时间: |
|
| 查看次数: |
582 次 |
| 最近记录: |