Je cherche à utiliser plusieurs threads pour accélérer un processus qui est très E/S lié. Je veux être en mesure d'appeler un service de repos avec des ID pris à partir d'un fichier CSV en boucle. Ce que je n'ai pas réussi à comprendre est comment séparer élégamment le fichier en morceaux en fonction de la quantité de threads que je veux utiliser.Ruby: Split et lire une partie d'un fichier En fonction de discussion Count
Le fichier CSV contient une seule colonne de ids comme ceci: ...
require 'benchmark'
require 'csv'
FILE_RECORD_COUNT = File.open("path-to-csv","r").readlines.size
def setup(thread_count)
threads = []
thread_count.times do
threads << Thread.new do
fetches_per_thread = FILE_RECORD_COUNT/thread_count
fetches_per_thread.times do
CSV.foreach("id_file.csv") do |id|
response = RestClient.get("https://api.examplerest/names?id={#id}",{accept: :json})
# do some quick validation...
end
end
end
end
threads.each(&:join)
end
def run_benchmark
Benchmark.bm(20) do |bm|
[1, 2, 3, 5, 6, 10, 15, 30, 100].each do |thread_count|
bm.report("with #{thread_count} threads") do
setup(thread_count)
end
end
end
end
Là où je suis perplexe, et où je besoin d'une solution est le bloc de code CSV.foreach(id_file.csv") do |id|...
. Je voudrais diviser les données dynamiquement et les nourrir dans chaque thread, puis faire un appel de repos. Je sais que je pourrais diviser le fichier manuellement, mais je voudrais éviter cela.
J'ai essayé de faire cela en un point de référence à partir d'un exemple, je trouve en ligne, pour voir où le sweet spot est pour le nombre de threads.
EDIT: En utilisant la réponse de BernardK, je suis en mesure d'exécuter mon code enfilée et je revins les résultats suivants:
| user | system | total | real |
with 1 threads 5.125000 2.594000 7.719000 (40.416162)
with 2 threads 1.625000 2.015000 3.640000 (28.571521)
with 3 threads 1.578000 1.625000 3.203000 (17.210526)
with 4 threads 1.578000 1.235000 2.813000 ( 8.496068)
with 5 threads 1.406000 1.250000 2.656000 ( 6.779216)
with 10 threads 1.875000 1.328000 3.203000 ( 5.069487)
with 15 threads 2.016000 1.640000 3.656000 ( 4.285426)
with 30 threads 2.125000 1.625000 3.750000 ( 3.817084)
with 100 threads 2.281000 1.375000 3.656000 ( 3.943304)
Ce fut un essai, mais montre vraiment comment les discussions comme celles-ci peuvent speedup Code Ruby!
S'il vous plaît attendre, il y a une erreur ('@ lines.each_slice' doit remplacer' thread_count.times'). – BernardK
@BernardK, d'accord, quand vous êtes-post, je vais mettre en œuvre vos modifications et vous faire savoir comment ça se passe. –
Terminé. (la version précédente lisait le fichier 'thread_count' fois) – BernardK