Skip to content

Instantly share code, notes, and snippets.

@doloopwhile
Created September 26, 2018 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doloopwhile/30654e6d86cac69a55dcfb4bb3001432 to your computer and use it in GitHub Desktop.
Save doloopwhile/30654e6d86cac69a55dcfb4bb3001432 to your computer and use it in GitHub Desktop.
active_job / delayed_job を高速化するハック ref: https://qiita.com/tonluqclml/items/f6a0411a8fbe3031cb0d
class CsvFormController < ApplicationController
# 「名前・年齢・メールアドレス」のCSVファイルをアップロードして、Userを作れる画面
#
# 太郎,32,taro@example.com
# 二郎,30,jiro@example.com
# 三郎,27,sabu@example.com
def upload
rows = CSV.parse(params[:file].read)
UserUploadJob.perform_later(rows: rows)
end
end
class UserUploadJob < ApplicationJob
def perform(rows:)
User.transaction do
rows.each do |row|
User.create!(name: row[0], age: row[1], email: row[2])
end
end
# 処理が終わったら、メールやSlackで通知
end
end
module Delayed
module Backend
module Base
...
def payload_object=(object)
@payload_object = object
self.handler = object.to_yaml
end
...
end
end
end
require 'benchmark'
require 'json'
require 'yaml'
large_array = (1..1_000_000).map { |x| [x, x, x] }
puts '.to_json'
puts Benchmark::CAPTION
puts Benchmark.measure { large_array.to_json }
puts
puts '.to_yaml'
puts Benchmark::CAPTION
puts Benchmark.measure { large_array.to_yaml }
.to_json
user system total real
0.180000 0.030000 0.210000 ( 0.218959)
.to_yaml
user system total real
30.350000 0.890000 31.240000 ( 33.154655)
class UserUploadJob
def serialize_arguments(args)
params = args.first.clone
# rows(配列の配列)を、TSV形式の文字列に変換
params[:rows] = params[:rows].map { |r| r.join("\t") }.join("\n")
super([params])
end
def deserialize_arguments(serialized_arguments)
args = super(serialized_arguments)
# TSV形式の文字列を配列の配列に変換
args.first[:entries] = args.first[:entries].lines.map { |l| l.strip.split("\t") }
args
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment