Advertisement
Guest User

Untitled

a guest
Dec 8th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.22 KB | None | 0 0
  1. require "bundler/inline"
  2.  
  3. gemfile(true) do
  4. ruby "2.3.4"
  5. source "https://rubygems.org"
  6. gem "activerecord", "5.0.0"
  7. gem "minitest", "5.9.0"
  8. gem "paper_trail", path: "..", require: false
  9. gem "sqlite3"
  10. gem "mysql2"
  11. gem "pg"
  12. end
  13.  
  14. require "active_record"
  15. require "minitest/autorun"
  16. require "logger"
  17. require "benchmark"
  18.  
  19. ActiveRecord::Base.establish_connection(
  20. :adapter => "mysql2",
  21. :host => "localhost",
  22. :username => "",
  23. :password => "",
  24. :database => "benchmark")
  25.  
  26. #adapter: "sqlite3", database: "benchmark.sqlite")
  27. '''
  28. :adapter => "postgresql",
  29. :host => "localhost",
  30. :username => "postgres",
  31. :password => "",
  32. :database => "benchmark"
  33. )'''
  34.  
  35. # #. database: ":memory:")
  36. ActiveRecord::Base.logger = nil
  37.  
  38. begin
  39. # we generate a large dataset, but we only read from it... so just take the last if there is any and don't throw an error
  40. ActiveRecord::Schema.define do
  41. create_table :physicians do |t|
  42. t.string :name
  43. t.timestamps
  44. end
  45.  
  46. create_table :patients do |t|
  47. t.string :name
  48. t.timestamps
  49. end
  50.  
  51. create_table :appointments do |t|
  52. t.belongs_to :physician, index: true
  53. t.belongs_to :patient, index: true
  54. t.datetime :appointment_date
  55. t.timestamps
  56. end
  57.  
  58. create_table :versions do |t|
  59. t.string :item_type, null: false
  60. t.integer :item_id, null: false
  61. t.string :event, null: false
  62. t.string :whodunnit
  63. t.text :object, limit: 1_073_741_823
  64. t.text :object_changes, limit: 1_073_741_823
  65. t.integer :transaction_id
  66. t.datetime :created_at
  67. end
  68. add_index :versions, %i[item_type item_id]
  69. add_index :versions, [:transaction_id]
  70.  
  71. create_table :version_associations do |t|
  72. t.integer :version_id
  73. t.string :foreign_key_name, null: false
  74. t.integer :foreign_key_id
  75. end
  76. add_index :version_associations, [:version_id]
  77. add_index :version_associations, %i[foreign_key_name foreign_key_id],
  78. name: "index_version_associations_on_foreign_key"
  79. end
  80. rescue
  81. end
  82.  
  83. #ActiveRecord::Base.logger = Logger.new(STDOUT)
  84. require "paper_trail/config"
  85.  
  86. PaperTrail::Config.instance.track_associations = true
  87.  
  88. require "paper_trail"
  89.  
  90. class Physician < ActiveRecord::Base
  91. has_many :appointments
  92. has_many :patients, through: :appointments
  93. has_paper_trail on: [:update]
  94. end
  95.  
  96. class Appointment < ActiveRecord::Base
  97. belongs_to :physician
  98. belongs_to :patient
  99. has_paper_trail on: [:update]
  100. end
  101.  
  102. class Patient < ActiveRecord::Base
  103. has_many :appointments
  104. has_many :physicians, through: :appointments
  105. has_paper_trail on: [:update]
  106. end
  107.  
  108.  
  109.  
  110. class PerformanceTest < ActiveSupport::TestCase
  111. setup do
  112. if PaperTrail::Version.count == 0
  113. physicians = 10
  114. patients = 10_000
  115. appointments = 10_000
  116.  
  117. changes_per_transaction = 10
  118. transactions = 10_000
  119.  
  120. puts "Generating Dataset"
  121. start = Time.now
  122. ActiveRecord::Base.transaction { generate_physicians(physicians) }
  123.  
  124. puts "Generated Physicians:", Physician.count, Time.now - start
  125. start = Time.now
  126. ActiveRecord::Base.transaction { generate_patients(patients) }
  127. puts "Generated Patients:", Patient.count, Time.now - start
  128. start = Time.now
  129. ActiveRecord::Base.transaction { generate_appointments(appointments) }
  130. puts "Generated Appointments: ", Appointment.count, Time.now - start
  131. start = Time.now
  132.  
  133. (0..transactions).each do |seed|
  134. ActiveRecord::Base.transaction { change_stuff(seed, changes_per_transaction) }
  135. puts "Changed Stuff (#{seed}): #{Time.now - start} "
  136. start = Time.now
  137. end
  138. end
  139. end
  140.  
  141. def check_performance_many(version)
  142. Benchmark.realtime { PaperTrail::Reifier::reify(version, has_many: true) }
  143. end
  144.  
  145. def check_performance_many_through(version)
  146. Benchmark.realtime { PaperTrail::Reifier::reify(version, has_many_through: true) }
  147. end
  148.  
  149. def check_performance(seed, type_name)
  150. rnd = Random.new(seed)
  151. number = 30
  152. has_many = 0
  153. has_many_through = 0
  154.  
  155. number.times do
  156. offset = rnd.rand(PaperTrail::Version.where(item_type: type_name).count)
  157. version = PaperTrail::Version.where(item_type: type_name).offset(offset).first
  158. has_many += check_performance_many(version)
  159. has_many_through += check_performance_many_through(version)
  160. end
  161. puts "#{type_name} has_many: #{has_many / number} has_many_through: #{has_many_through}"
  162. end
  163.  
  164. def generate_physicians(amount)
  165. count = Physician.count
  166. (count...amount).each do |index|
  167. real_index = index
  168. Physician.new(name: "Physician #{real_index}").save(validate: false)
  169. end
  170. end
  171.  
  172. def generate_patients(amount)
  173. count = Patient.count
  174. (count...amount).each do |index|
  175. real_index = index
  176. Patient.new(name: "Patient #{real_index}").save(validate: false)
  177. end
  178. end
  179.  
  180. def generate_appointments(relations)
  181. date = Date.new(2018, 1, 1)
  182. patients = Patient.count
  183. physicians = Physician.count
  184. count = Appointment.count
  185. rnd = Random.new(0)
  186. (count...relations).each do |index|
  187. patient_id = rnd.rand(patients) + 1
  188. physician_id = rnd.rand(physicians) + 1
  189. Appointment.new(appointment_date: date, patient_id: patient_id, physician_id: physician_id).save(validate: false)
  190. end
  191. end
  192.  
  193. def change_stuff(seed, changes)
  194. patients = Patient.count
  195. physicians = Physician.count
  196. appointments = Appointment.count
  197.  
  198. rnd = Random.new(seed)
  199. date = Date.new(2018, 1, 1)
  200. (0..changes).each do |index|
  201. appointment = rnd.rand(appointments) + 1
  202. day = rnd.rand(1000)
  203. Appointment.find(appointment).update(appointment_date: date + day)
  204.  
  205. patient = rnd.rand(patients) + 1
  206. name = rnd.rand
  207. Patient.find(patient).update(name: "Patient #{patient} #{name}")
  208.  
  209. physician = rnd.rand(physicians) + 1
  210. name = rnd.rand
  211. Physician.find(physician).update(name: "Physician #{physician} #{name}")
  212. end
  213. end
  214.  
  215. def test_has_many
  216. #ActiveRecord::Base.logger = Logger.new(STDOUT)
  217. check_performance(0, 'Patient')
  218. check_performance(0, 'Physician')
  219. end
  220. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement