aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/object/deep_dup.rb
Commit message (Collapse)AuthorAgeFilesLines
* [Active Support] require_relative => requireAkira Matsuda2017-10-211-1/+1
| | | | This basically reverts 8da30ad6be34339124ba4cb4e36aea260dda12bc
* [Active Support] `rubocop -a --only Layout/EmptyLineAfterMagicComment`Koichi ITO2017-07-111-0/+1
|
* Use frozen-string-literal in ActiveSupportKir Shatrov2017-07-091-0/+1
|
* [Active Support] require => require_relativeAkira Matsuda2017-07-011-1/+1
|
* applies new string literal convention in activesupport/libXavier Noria2016-08-061-1/+1
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* drop array allocations when iterating over the hashAaron Patterson2015-10-151-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `each_with_object` allocates an array for each kv pair. Switching to the slightly more verbose but less allocatey `each_pair` eliminates array allocations. Eliminating this allocation returns AR objects to have constant array allocations regardless of the number of columns the object has. Here is test code: ```ruby require 'active_record' class Topic < ActiveRecord::Base end 20.times do |i| Process.waitpid fork { ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:' ActiveRecord::Base.connection.instance_eval do create_table(:topics) do |t| t.string :title, limit: 250 t.string :author_name t.string :author_email_address t.string :parent_title t.string :type t.string :group i.times do |j| t.string :"aaa#{j}" end t.timestamps null: true end end ObjectSpace::AllocationTracer.setup(%i{type}) Topic.create title: "aaron" # heat cache result = ObjectSpace::AllocationTracer.trace do 10.times do |i| Topic.create title: "aaron #{i}" end end puts "#{Topic.columns.length},#{(result.find { |k,v| k.first == :T_ARRAY }.last.first / 10)}" } end ``` Before this commit: ``` 9,166 10,167 11,168 12,169 13,170 14,171 15,172 16,173 17,174 18,175 19,176 20,177 21,178 22,179 23,180 24,181 25,182 26,183 27,184 28,185 ``` After: ``` 9,157 10,157 11,157 12,157 13,157 14,157 15,157 16,157 17,157 18,157 19,157 20,157 21,157 22,157 23,157 24,157 25,157 26,157 27,157 28,157 ``` Left side is the number of columns, right is the number of allocations
* make string allocation constant regardless of column countAaron Patterson2015-10-151-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | deep_dup'ing a hash will dup the keys as well as the values. Since string keys from the source hash will be frozen, and the dup'd objects are immediately dup'd and frozen on insert in to the hash, the end user will only ever see two frozen strings. Since the strings are immutable, this commit just cheats a little and reuses the immutable strings. Just to reiterate, before this commit, deep duping a hash that looks like this: `{ "foo" => "bar" }` will generate two new instances of "foo". One is created when `deep_dup` is called on "foo", and the other is created when the newly allocated "foo" string is inserted in to the hash. The user never sees the intermediate "foo", and both copies of "foo" that the user *can* access will be frozen, so in this case we just reuse the existing frozen key. The upshot is that after this change, string allocations on AR allocations become constant regardless of the number of columns the model has. ```ruby require 'active_record' class Topic < ActiveRecord::Base end 20.times do |i| Process.waitpid fork { ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:' ActiveRecord::Base.connection.instance_eval do create_table(:topics) do |t| t.string :title, limit: 250 t.string :author_name t.string :author_email_address t.string :parent_title t.string :type t.string :group i.times do |j| t.integer :"aaa#{j}" end t.timestamps null: true end end ObjectSpace::AllocationTracer.setup(%i{type}) Topic.create title: "aaron" # heat cache result = ObjectSpace::AllocationTracer.trace do 10.times do |i| Topic.create title: "aaron #{i}" end end puts "#{Topic.columns.length},#{(result.find { |k,v| k.first == :T_STRING }.last.first / 10)}" } end ``` If you run the above script before this commit, the output looks like this: ``` [aaron@TC rails (master)]$ be ruby -rallocation_tracer test.rb 9,105 10,107 11,109 12,111 13,113 14,115 15,117 16,119 17,121 18,123 19,125 20,127 21,129 22,131 23,133 24,135 25,137 26,139 27,141 28,143 ``` The left column is the number of methods, the right column is the number of string allocations. Running against this commit, the output is: ``` [aaron@TC rails (master)]$ be ruby -rallocation_tracer test.rb 9,87 10,87 11,87 12,87 13,87 14,87 15,87 16,87 17,87 18,87 19,87 20,87 21,87 22,87 23,87 24,87 25,87 26,87 27,87 28,87 ``` As you can see, there is now only a constant number of strings allocated, regardless of the number of columns the model has.
* deep_dup method, remove old key from duplicated hash to avoid unnecessary pairsMehmet Emin İNAÇ2015-05-041-0/+1
|
* Pass symbol as an argument instead of a blockErik Michaels-Ober2014-11-291-1/+1
|
* Change syntax format for example returned valuesPrem Sichanugrist2013-11-111-6/+6
| | | | | | | | | According to our guideline, we leave 1 space between `#` and `=>`, so we want `# =>` instead of `#=>`. Thanks to @fxn for the suggestion. [ci skip]
* Replace comments' non-breaking spaces with spacesclaudiob2012-12-041-1/+1
| | | | | | | | | | Sometimes, on Mac OS X, programmers accidentally press Option+Space rather than just Space and don’t see the difference. The problem is that Option+Space writes a non-breaking space (0XA0) rather than a normal space (0x20). This commit removes all the non-breaking spaces inadvertently introduced in the comments of the code.
* Add missing requires for deep_dup and hash ext testCarlos Antonio da Silva2012-05-241-0/+2
|
* adding examples to deep_dup methodFrancesco Rodriguez2012-05-141-1/+23
|
* Keep all methods in object/deep_dupPiotr Sarnacki2012-05-061-0/+16
|
* Nice logic for deep_dup in railsAlexey Gaziev2012-05-061-0/+6