Created
June 21, 2010 16:04
-
-
Save thinkerbot/447072 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'benchmark' | |
| require 'active_record' | |
| ActiveRecord.load_all! | |
| # ActiveRecord::Base.logger = Logger.new(STDERR) | |
| ActiveRecord::Base.establish_connection( | |
| :adapter => "sqlite3", | |
| :dbfile => ":memory:" | |
| ) | |
| ActiveRecord::Schema.define do | |
| create_table :ones do |table| | |
| table.column :field1, :number | |
| end | |
| create_table :tens do |table| | |
| 0.upto(10) do |i| | |
| table.column "field#{i}".to_sym, :number | |
| end | |
| end | |
| create_table :hundreds do |table| | |
| 0.upto(100) do |i| | |
| table.column "field#{i}".to_sym, :number | |
| end | |
| end | |
| end | |
| class One < ActiveRecord::Base | |
| end | |
| class Ten < ActiveRecord::Base | |
| end | |
| class Hundred < ActiveRecord::Base | |
| end | |
| Benchmark.bm(20) do |x| | |
| n = 1000 | |
| one_attrs = {:field1 => 1} | |
| ten_attrs = {}; 0.upto(10) {|i| ten_attrs["field#{i}".to_sym] = i } | |
| hun_attrs = {}; 0.upto(100) {|i| hun_attrs["field#{i}".to_sym] = i } | |
| x.report("One.new") do | |
| n.times { One.new } | |
| end | |
| x.report("One.new(attrs)") do | |
| n.times { One.new(one_attrs) } | |
| end | |
| x.report("Ten.new(attrs)") do | |
| n.times { Ten.new(ten_attrs) } | |
| end | |
| x.report("Hundred.new(attrs)") do | |
| n.times { Hundred.new(hun_attrs) } | |
| end | |
| x.report("One.first") do | |
| n.times { One.first } | |
| end | |
| x.report("Ten.first") do | |
| n.times { Ten.first } | |
| end | |
| x.report("Hundred.first") do | |
| n.times { Hundred.first } | |
| end | |
| puts | |
| puts "optimimized" | |
| require 'optimization' | |
| x.report("One.new") do | |
| n.times { One.new } | |
| end | |
| x.report("One.new(attrs)") do | |
| n.times { One.new(one_attrs) } | |
| end | |
| x.report("Ten.new(attrs)") do | |
| n.times { Ten.new(ten_attrs) } | |
| end | |
| x.report("Hundred.new(attrs)") do | |
| n.times { Hundred.new(hun_attrs) } | |
| end | |
| x.report("One.first") do | |
| n.times { One.first } | |
| end | |
| x.report("Ten.first") do | |
| n.times { Ten.first } | |
| end | |
| x.report("Hundred.first") do | |
| n.times { Hundred.first } | |
| end | |
| end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ActiveRecord::Base | |
| class << self | |
| def attributes_protected_from_mass_assignment | |
| @attributes_protected_from_mass_assignment ||= begin | |
| if accessible_attributes.nil? && protected_attributes.nil? | |
| attributes_protected_by_default | |
| elsif protected_attributes.nil? | |
| (accessible_attributes + attributes_protected_by_default).uniq | |
| elsif accessible_attributes.nil? | |
| (protected_attributes + attributes_protected_by_default).uniq | |
| else | |
| raise "Declare either attr_protected or attr_accessible for #{self}, but not both." | |
| end | |
| end | |
| end | |
| def attributes_protected_by_default | |
| default = [ primary_key, inheritance_column ] | |
| default << 'id' unless primary_key.eql? 'id' | |
| default | |
| end | |
| def writer_hash | |
| @writer_hash ||= begin | |
| Hash.new do |hash, k| | |
| hash[k] = instance_methods.include?("#{k}=") ? "#{k}=".to_sym : nil | |
| end | |
| end | |
| end | |
| end | |
| def attributes=(new_attributes, guard_protected_attributes = true) | |
| return if new_attributes.nil? | |
| attributes = new_attributes.stringify_keys | |
| multi_parameter_attributes = [] | |
| attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes | |
| attributes.each do |k, v| | |
| if k.include?("(") | |
| multi_parameter_attributes << [ k, v ] | |
| else | |
| writer = self.class.writer_hash[k] or raise(UnknownAttributeError, "unknown attribute: #{k}") | |
| send(writer, v) | |
| end | |
| end | |
| assign_multiparameter_attributes(multi_parameter_attributes) | |
| end | |
| def remove_attributes_protected_from_mass_assignment(attributes) | |
| removed_attributes = attributes.keys & self.class.attributes_protected_from_mass_assignment | |
| if removed_attributes.any? | |
| log_protected_attribute_removal(removed_attributes) | |
| end | |
| attributes = attributes.dup | |
| removed_attributes.each {|key| attributes.delete(key) } | |
| attributes | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment