Skip to content

Instantly share code, notes, and snippets.

@kaikuchn
Last active December 7, 2015 08:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaikuchn/67a8652aa7bda77edd7a to your computer and use it in GitHub Desktop.
Save kaikuchn/67a8652aa7bda77edd7a to your computer and use it in GitHub Desktop.
bulk insert benchmark
#!/usr/bin/env ruby
require 'benchmark'
require File.expand_path('../config/environment', __FILE__)
begin
@list = (0..10_000).map{|i| {word: "word_#{i}", word_translation: "translation_#{i}"}}
@vocabulary_1 = Vocabulary.create(user_id: User.first.id, title: "Vocabulary #1")
@vocabulary_2 = Vocabulary.create(user_id: User.first.id, title: "Vocabulary #2")
@vocabulary_3 = Vocabulary.create(user_id: User.first.id, title: "Vocabulary #3")
def run_naive_approach
@vocable_ids3 = @list.map{|v| v = Vocable.create(v.merge({vocabulary_id: @vocabulary_3.id}).slice(:vocabulary_id, :word, :word_translation)); v.id || v.errors.messages }
end
def run_ar_in_transaction
ActiveRecord::Base.transaction do
@vocable_ids1 = @list.map{|v| v = Vocable.create(v.merge({vocabulary_id: @vocabulary_1.id}).slice(:vocabulary_id, :word, :word_translation)); v.id || v.errors.messages }
end
end
def run_sql_insert_with_validations
@vocables = @list.map{|v| Vocable.new(v.merge({vocabulary_id: @vocabulary_2.id}).slice(:vocabulary_id, :word, :word_translation))}
@vocables.uniq!{|v| [v.word, v.word_translation]}
@vocables.map!{|v| v.valid? ? {valid: true, vocable: v} : {valid: false, errors: v.errors} }
return @vocables if @vocables.all?{|v| !v[:valid] }
@vocable_ids2 = Vocable.connection.execute("INSERT INTO vocables (vocabulary_id, word, word_translation) VALUES #{@vocables.map{|v| v[:valid] ? "(#{v[:vocable].vocabulary_id}, '#{v[:vocable].word}', '#{v[:vocable].word_translation}')" : nil }.compact.join(', ')} RETURNING id").column_values(0)
end
Benchmark.bm(34) do |b|
b.report("Naive create calls") { run_naive_approach }
b.report("AR Create wrapped in a transaction") { run_ar_in_transaction }
b.report("SQL insert with AR validation") { run_sql_insert_with_validations }
end
ensure
@vocabulary_1.delete
@vocabulary_2.delete
@vocabulary_3.delete
end
@fahadgudu
Copy link

very handy gist much appreciated (y)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment