Не думаю, что ваш веб-хостер будет доволен таким решением. Этот скрипт
dict = {}
(0..1000_000).each do | num |
dict[/#{num}/] = "#{num}_subst"
end
потребляет гигабайт оперативной памяти на моем MBP для хранения хеш-таблицы. Другим подходом будет сохранение ваших замен, маршалированных в memcached, чтобы вы могли (по крайней мере) хранить их на разных машинах.
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
Вам нужно будет позаботиться о том, чтобы клавиши оставались «горячими», так как 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"
Чтобы заполнить файл И загрузить каждую замену, мне понадобится:
real 0m21.262s
user 0m19.100s
sys 0m0.502s
Просто загрузить регулярное выражение и строку из файла (все миллионы, по частям)
real 0m7.855s
user 0m7.645s
sys 0m0.105s
Так что это 7 секунд на ввод-вывод, но вы не потеряете память (и есть огромные возможности для улучшения) - RSIZE составляет около 3 мегабайт. Вы легко сможете заставить его работать быстрее, если вы выполните массовый ввод-вывод или сделаете один файл для 10-50 замен и загрузите их целиком. Поместите файлы на SSD или RAID, и вы получите победителя, но вы сможете сохранить свою оперативную память.