aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/callbacks.rb
Commit message (Collapse)AuthorAgeFilesLines
* fix typo in in define_model_callbacks comment [ci skip]Ryan Selk2014-10-031-1/+1
|
* add notes for `define_model_callbacks` [ci skip]Kuldeep Aggarwal2014-10-031-0/+3
|
* Reduce allocations when running AR callbacks.Pete Higgins2014-09-281-6/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Inspired by @tenderlove's work in c363fff29f060e6a2effe1e4bb2c4dd4cd805d6e, this reduces the number of strings allocated when running callbacks for ActiveRecord instances. I measured that using this script: ``` require 'objspace' require 'active_record' require 'allocation_tracer' ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:" ActiveRecord::Base.connection.instance_eval do create_table(:articles) { |t| t.string :name } end class Article < ActiveRecord::Base; end a = Article.create name: "foo" a = Article.find a.id N = 10 result = ObjectSpace::AllocationTracer.trace do N.times { Article.find a.id } end result.sort.each do |k,v| p k => v end puts "total: #{result.values.map(&:first).inject(:+)}" ``` When I run this against master and this branch I get this output: ``` pete@balloon:~/projects/rails/activerecord$ git checkout master M Gemfile Switched to branch 'master' pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_before pete@balloon:~/projects/rails/activerecord$ git checkout remove-dynamic-send-on-built-in-callbacks M Gemfile Switched to branch 'remove-dynamic-send-on-built-in-callbacks' pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_after pete@balloon:~/projects/rails/activerecord$ diff allocations_before allocations_after 39d38 < {["/home/pete/projects/rails/activesupport/lib/active_support/callbacks.rb", 81]=>[40, 0, 0, 0, 0, 0]} 42c41 < total: 630 --- > total: 590 ``` In addition to this, there are two micro-optimizations present: * Using `block.call if block` vs `yield if block_given?` when the block was being captured already. ``` pete@balloon:~/projects$ cat benchmark_block_call_vs_yield.rb require 'benchmark/ips' def block_capture_with_yield &block yield if block_given? end def block_capture_with_call &block block.call if block end def no_block_capture yield if block_given? end Benchmark.ips do |b| b.report("block_capture_with_yield") { block_capture_with_yield } b.report("block_capture_with_call") { block_capture_with_call } b.report("no_block_capture") { no_block_capture } end pete@balloon:~/projects$ ruby benchmark_block_call_vs_yield.rb Calculating ------------------------------------- block_capture_with_yield 124979 i/100ms block_capture_with_call 138340 i/100ms no_block_capture 136827 i/100ms ------------------------------------------------- block_capture_with_yield 5703108.9 (±2.4%) i/s - 28495212 in 4.999368s block_capture_with_call 6840730.5 (±3.6%) i/s - 34169980 in 5.002649s no_block_capture 5821141.4 (±2.8%) i/s - 29144151 in 5.010580s ``` * Defining and calling methods instead of using send. ``` pete@balloon:~/projects$ cat benchmark_method_call_vs_send.rb require 'benchmark/ips' class Foo def tacos nil end end my_foo = Foo.new Benchmark.ips do |b| b.report('send') { my_foo.send('tacos') } b.report('call') { my_foo.tacos } end pete@balloon:~/projects$ ruby benchmark_method_call_vs_send.rb Calculating ------------------------------------- send 97736 i/100ms call 151142 i/100ms ------------------------------------------------- send 2683730.3 (±2.8%) i/s - 13487568 in 5.029763s call 8005963.9 (±2.7%) i/s - 40052630 in 5.006604s ``` The result of this is making typical ActiveRecord operations slightly faster: https://gist.github.com/phiggins/e46e51dcc7edb45b5f98
* Fix ActiveSupport::Callbacks #set_callback docs.Nick Pellant2014-07-071-1/+1
| | | | | | A minor version breakage due to a rewrite of the callbacks code now requires an explicit block to be passed to #set_callback. This amends the documentation.
* :fire: these are lambdas now [ci skip]Godfrey Chan2014-07-031-9/+2
| | | This has changed since around 2b1500d6
* Tiny documentation fixes [ci skip]Robin Dupret2014-06-291-1/+1
|
* Update documentation for run_callbacksjamesprior2014-06-271-1/+2
| | | In some cases run_callbacks will return nil. I'm attempting to update the documentation for the method to clarify.
* remove deprecation warningeileencodes2014-05-131-6/+0
| | | | | This deprecation was released in 4.1.0 and can be removed for 4.2.0, deprecation message / handling is no longer necessary.
* flip conditional to use if/else instead of unless/elseeileencodes2014-05-121-3/+3
| | | | Use if/else instead of unless/else so conditional reads better.
* Merge pull request #11411 from dscataglini/masterAaron Patterson2014-04-091-6/+12
|\ | | | | Active support callback's before/after/around filters are not correctly making their singleton methods private
| * private method doesn't work for singleton methods defined this wayDiego Scataglini2013-07-121-6/+12
| |
* | Fix few typos in the documentation [ci skip]Robin Dupret2013-12-211-1/+1
| |
* | Merge pull request #13287 from aayushkhandelwal11/typo_rectifiedYves Senn2013-12-111-3/+3
|\ \ | | | | | | typos rectified lifecycle => life cycle
| * | typos rectified lifecycle => life cycleAayush khandelwal2013-12-121-3/+3
| | |
* | | typos rectified [ci skip]Aayush khandelwal2013-12-121-1/+1
|/ /
* / Fix typo in set_callback docs. [ci skip]Gilad Zohari2013-09-061-1/+1
|/
* Revert "remove string based terminators for `ActiveSupport::Callbacks`."Yves Senn2013-07-051-0/+6
| | | | | | | | This reverts commit d108672dada7ba97d3b3b56f0c6001cea621061e. Conflicts: activesupport/CHANGELOG.md
* remove string based terminators for `ActiveSupport::Callbacks`.Yves Senn2013-07-051-6/+0
|
* Further clean-up of ActiveSupport::CallbacksGenadi Samokovarov2013-07-011-10/+9
| | | | | | | | | | | | | | | | | In #11195 I noticed a trailing comma in the docs, but I decided to further clean it up. What I have done: * Clean up the trailing comma in the docs and some extra whitespace lines. * Used `Array#extract` options to factor the repetitive pattern of `args.last.is_a(Hash) ? ...` * Renamed the local var `config` to `options` in `define_callbacks`, as `options` seems to be the de facto name for the options objects. * Renamed the local var `l` to `line` in `define_callback` (maybe it meant `lambda` in the context) as single `l` may look like `1` in some fonts.
* unified the param names across all callbacks manipulation methodsSteven Yang2013-07-011-10/+10
| | | | | | | _ Rename the define_callbacks params to `names` - in order to match the naming conventions for `get_callbacks` and `set_callbacks` at https://github.com/rails/rails/blob/master/activesupport/lib/active_support/callbacks.rb#L736-743 - `define_callbacks` just register names(events), not define the real callback functions. - Rename the `reset_callbacks` params
* updated AS:Callbacks doc for terminator option in define_callbacks methodSteven Yang2013-06-301-3/+4
| | | | The change is commited at ba552764344bc0a3c25b8576ec11f127ceaa16da
* remove some evals from callback conditionalsAaron Patterson2013-06-111-0/+10
|
* Fixed typos in activesupport [ci skip]Prathamesh Sonpatki2013-06-091-3/+3
| | | | | - eval'ed to eval'd in accordance with https://github.com/rails/rails/pull/10889 - tried to improve statement about compiling Procs into methods using define_method
* "normalize_callback_params" doesn't require name paramVipul A M2013-05-171-3/+3
|
* Revert "just call the class method since we know the callbacks are stored at ↵Aaron Patterson2013-05-161-2/+1
| | | | | | the" This reverts commit 55975c71ec9c2c18b67020484959ff5c69d4d3fb.
* just call the class method since we know the callbacks are stored at theAaron Patterson2013-05-151-1/+2
| | | | class level
* remove dead codeAaron Patterson2013-05-151-23/+4
|
* remove deprecation noticesAaron Patterson2013-05-151-10/+0
|
* stop keeping a reference to the options hashAaron Patterson2013-05-151-12/+7
|
* conditions are guaranteed to be arrays by initializeAaron Patterson2013-05-151-2/+2
|
* simplify the condions lambda generationAaron Patterson2013-05-151-12/+2
|
* use unless instead of if!Aaron Patterson2013-05-151-3/+3
|
* only dup the options once, the Callback object does not mutate themAaron Patterson2013-05-141-2/+2
|
* make the compile method thread safeAaron Patterson2013-05-141-5/+7
|
* use inject rather than multiple assignmentsAaron Patterson2013-05-141-4/+2
|
* deprecating string based terminatorsAaron Patterson2013-05-141-4/+11
|
* halting lambda must be instance execedAaron Patterson2013-05-141-2/+2
|
* fixing arity2 testAaron Patterson2013-05-141-3/+8
|
* fix shadowed variable warningsAaron Patterson2013-05-141-5/+5
|
* polymorphic around callbacksAaron Patterson2013-05-141-15/+79
|
* polymorphic after filterAaron Patterson2013-05-141-25/+70
|
* rename terminal to halting, try to keep naming consistentAaron Patterson2013-05-141-4/+4
|
* push the before filter lambdas to factory methodsAaron Patterson2013-05-141-40/+58
|
* polymorphic before callbacksAaron Patterson2013-05-141-16/+54
|
* use a singleton end nodeAaron Patterson2013-05-131-5/+10
|
* Revert "we never pass blocks, so remove this"Aaron Patterson2013-05-131-1/+1
| | | | This reverts commit 9caf0cf9c8c7b42737ae78c470a5dd2f583ada75.
* if there is nothing to compile, then do not bother compilingAaron Patterson2013-05-131-3/+8
|
* Arrays are no longer supportedAaron Patterson2013-05-131-4/+0
|
* we never pass blocks, so remove thisAaron Patterson2013-05-131-1/+1
|
* raise an argument error if the filter arity is greater than 1Aaron Patterson2013-05-131-12/+6
|