Guest User

Untitled

a guest
Feb 21st, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.62 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2.  
  3. require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core')
  4. require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core', 'version')
  5.  
  6. require 'rubygems'
  7. require 'ftools'
  8.  
  9. # sudo gem install rbench
  10. # OR git clone git://github.com/somebee/rbench.git , rake install
  11. gem 'rbench', '>=0.2.2'
  12. require 'rbench'
  13.  
  14. gem 'faker', '>=0.3.1'
  15. require 'faker'
  16.  
  17. gem 'activerecord', '>=2.2.1'
  18. require 'active_record'
  19. require 'active_record/version'
  20.  
  21. configuration_options = {
  22. :adapter => 'postgresql',
  23. :username => 'drogus',
  24. :password => 'secret',
  25. :database => 'data_mapper_1',
  26. }
  27.  
  28.  
  29. log_dir = DataMapper.root / 'log'
  30. log_dir.mkdir unless log_dir.directory?
  31.  
  32. DataMapper::Logger.new(log_dir / 'dm.log', :info)
  33. adapter = DataMapper.setup(:default, "postgres://drogus:secret@localhost/data_mapper_1")
  34.  
  35. if configuration_options[:adapter]
  36. sqlfile = File.join(File.dirname(__FILE__),'..','tmp','performance.sql')
  37. mysql_bin = %w[mysql mysql5].select{|bin| `which #{bin}`.length > 0 }
  38. mysqldump_bin = %w[mysqldump mysqldump5].select{|bin| `which #{bin}`.length > 0 }
  39. end
  40.  
  41. ActiveRecord::Base.logger = Logger.new(log_dir / 'ar.log')
  42. ActiveRecord::Base.logger.level = 0
  43.  
  44. ActiveRecord::Base.establish_connection(configuration_options)
  45.  
  46. class ARExhibit < ActiveRecord::Base #:nodoc:
  47. set_table_name 'exhibits'
  48.  
  49. belongs_to :user, :class_name => 'ARUser', :foreign_key => 'user_id'
  50. end
  51.  
  52. class ARUser < ActiveRecord::Base #:nodoc:
  53. set_table_name 'users'
  54.  
  55. has_many :exhibits, :foreign_key => 'user_id'
  56.  
  57. end
  58.  
  59. ARExhibit.find_by_sql('SELECT 1')
  60.  
  61. class Exhibit
  62. include DataMapper::Resource
  63.  
  64. property :id, Serial
  65. property :name, String
  66. property :zoo_id, Integer
  67. property :user_id, Integer
  68. property :notes, Text, :lazy => true
  69. property :created_on, Date
  70.  
  71. belongs_to :user
  72. # property :updated_at, DateTime
  73. end
  74.  
  75. class User
  76. include DataMapper::Resource
  77.  
  78. property :id, Serial
  79. property :name, String
  80. property :email, String
  81. property :about, Text, :lazy => true
  82. property :created_on, Date
  83.  
  84. end
  85.  
  86. touch_attributes = lambda do |exhibits|
  87. [*exhibits].each do |exhibit|
  88. exhibit.id
  89. exhibit.name
  90. exhibit.created_on
  91. end
  92. end
  93.  
  94. touch_relationships = lambda do |exhibits|
  95. [*exhibits].each do |exhibit|
  96. exhibit.id
  97. exhibit.name
  98. exhibit.created_on
  99. exhibit.user
  100. end
  101. end
  102.  
  103.  
  104. c = configuration_options
  105.  
  106. if sqlfile && File.exists?(sqlfile)
  107. puts "Found data-file. Importing from #{sqlfile}"
  108. #adapter.execute("LOAD DATA LOCAL INFILE '#{sqlfile}' INTO TABLE exhibits")
  109. `psql #{c[:database]} < #{sqlfile}`
  110. else
  111.  
  112. puts "Generating data for benchmarking..."
  113.  
  114. User.auto_migrate!
  115. Exhibit.auto_migrate!
  116.  
  117. users = []
  118. exhibits = []
  119.  
  120. # pre-compute the insert statements and fake data compilation,
  121. # so the benchmarks below show the actual runtime for the execute
  122. # method, minus the setup steps
  123.  
  124. # Using the same paragraph for all exhibits because it is very slow
  125. # to generate unique paragraphs for all exhibits.
  126. paragraph = Faker::Lorem.paragraphs.join($/)
  127.  
  128. 10_000.times do |i|
  129. users << [
  130. 'INSERT INTO users (name,email,created_on) VALUES (?, ?, ?)',
  131. Faker::Name.name,
  132. Faker::Internet.email,
  133. Date.today
  134. ]
  135.  
  136. exhibits << [
  137. 'INSERT INTO exhibits (name, zoo_id, user_id, notes, created_on) VALUES (?, ?, ?, ?, ?)',
  138. Faker::Company.name,
  139. rand(10).ceil,
  140. i,
  141. paragraph,#Faker::Lorem.paragraphs.join($/),
  142. Date.today
  143. ]
  144. end
  145.  
  146. puts "Inserting 10,000 users..."
  147. 10_000.times { |i| adapter.execute(*users.at(i)) }
  148. puts "Inserting 10,000 exhibits..."
  149. 10_000.times { |i| adapter.execute(*exhibits.at(i)) }
  150.  
  151. if sqlfile
  152. answer = nil
  153. until answer && answer[/^$|y|yes|n|no/]
  154. print("Would you like to dump data into tmp/performance.sql (for faster setup)? [Yn]");
  155. STDOUT.flush
  156. answer = gets
  157. end
  158.  
  159. if answer[/^$|y|yes/]
  160. File.makedirs(File.dirname(sqlfile))
  161. #adapter.execute("SELECT * INTO OUTFILE '#{sqlfile}' FROM exhibits;")
  162. `pg_dump #{c[:database]} -a > #{sqlfile}`
  163. puts "File saved\n"
  164. end
  165. end
  166.  
  167. end
  168.  
  169. TIMES = ENV['x'] ? ENV['x'].to_i : 10_000
  170.  
  171. puts "You can specify how many times you want to run the benchmarks with rake:perf x=(number)"
  172. puts "Some tasks will be run 10 and 1000 times less than (number)"
  173. puts "Benchmarks will now run #{TIMES} times"
  174. # Inform about slow benchmark
  175. # answer = nil
  176. # until answer && answer[/^$|y|yes|n|no/]
  177. # print("A slow benchmark exposing problems with SEL is newly added. It takes approx. 20s\n");
  178. # print("you have scheduled it to run #{TIMES / 100} times.\nWould you still include the particular benchmark? [Yn]")
  179. # STDOUT.flush
  180. # answer = gets
  181. # end
  182. # run_rel_bench = answer[/^$|y|yes/] ? true : false
  183.  
  184.  
  185. RBench.run(TIMES) do
  186.  
  187. column :times
  188. column :ar, :title => "AR #{ActiveRecord::VERSION::STRING}"
  189. column :dm, :title => "DM #{DataMapper::VERSION}"
  190. column :diff, :compare => [:ar,:dm]
  191.  
  192. report "Model.new (instantiation)" do
  193. ar { ARExhibit.new }
  194. dm { Exhibit.new }
  195. end
  196.  
  197. report "Model.new (setting attributes)" do
  198. attrs = {:name => 'sam', :zoo_id => 1}
  199. ar { ARExhibit.new(attrs) }
  200. dm { Exhibit.new(attrs) }
  201. end
  202.  
  203. report "Model.get specific (not cached)" do
  204. ActiveRecord::Base.uncached { ar { touch_attributes[ARExhibit.find(1)] } }
  205. dm { touch_attributes[Exhibit.get(1)] }
  206. end
  207.  
  208. report "Model.get specific (cached)" do
  209. ActiveRecord::Base.cache { ar { touch_attributes[ARExhibit.find(1)] } }
  210. Exhibit.repository(:default) { dm { touch_attributes[Exhibit.get(1)] } }
  211. end
  212.  
  213. report "Model.first" do
  214. ar { touch_attributes[ARExhibit.first] }
  215. dm { touch_attributes[Exhibit.first] }
  216. end
  217.  
  218. report "Model.all limit(100)", (TIMES / 10.0).ceil do
  219. ar { touch_attributes[ARExhibit.find(:all, :limit => 100)] }
  220. dm { touch_attributes[Exhibit.all(:limit => 100)] }
  221. end
  222.  
  223. report "Model.all limit(100) with relationship", (TIMES / 10.0).ceil do
  224. ar { touch_relationships[ARExhibit.all(:limit => 100, :include => [:user])] }
  225. dm { touch_relationships[Exhibit.all(:limit => 100)] }
  226. end
  227.  
  228. report "Model.all limit(10,000)", (TIMES / 1000.0).ceil do
  229. ar { touch_attributes[ARExhibit.find(:all, :limit => 10_000)] }
  230. dm { touch_attributes[Exhibit.all(:limit => 10_000)] }
  231. end
  232.  
  233. create_exhibit = {
  234. :name => Faker::Company.name,
  235. :zoo_id => rand(10).ceil,
  236. :notes => Faker::Lorem.paragraphs.join($/),
  237. :created_on => Date.today
  238. }
  239.  
  240. report "Model.create" do
  241. ar { ARExhibit.create(create_exhibit) }
  242. dm { Exhibit.create(create_exhibit) }
  243. end
  244.  
  245. report "Resource#attributes" do
  246. attrs_first = {:name => 'sam', :zoo_id => 1}
  247. attrs_second = {:name => 'tom', :zoo_id => 1}
  248. ar { e = ARExhibit.new(attrs_first); e.attributes = attrs_second }
  249. dm { e = Exhibit.new(attrs_first); e.attributes = attrs_second }
  250. end
  251.  
  252. report "Resource#update" do
  253. ar { e = ARExhibit.find(1); e.name = 'bob'; e.save }
  254. dm { e = Exhibit.get(1); e.name = 'bob'; e.save }
  255. end
  256.  
  257. report "Resource#destroy" do
  258. ar { ARExhibit.first.destroy }
  259. dm { Exhibit.first.destroy }
  260. end
  261.  
  262. report "Model.transaction" do
  263. ar { ARExhibit.transaction { ARExhibit.new } }
  264. dm { Exhibit.transaction { Exhibit.new } }
  265. end
  266.  
  267. summary "Total"
  268. end
  269.  
  270. connection = adapter.send(:create_connection)
  271. command = connection.create_command("DROP TABLE exhibits")
  272. command = connection.create_command("DROP TABLE users")
  273. command.execute_non_query rescue nil
  274. connection.close
Add Comment
Please, Sign In to add comment