chaps-io / access-granted

Multi-role and whitelist based authorization gem for Rails (and not only Rails!)
MIT License
774 stars 41 forks source link

optimize lookup #1

Closed farnoy closed 10 years ago

farnoy commented 10 years ago

Before

Total: 263 samples
      89  33.8%  33.8%      250  95.1% Array#select
      61  23.2%  57.0%       66  25.1% AccessGranted::Permission#matches_action?
      52  19.8%  76.8%      161  61.2% AccessGranted::Permission#relevant?
      20   7.6%  84.4%       43  16.3% AccessGranted::Permission#matches_subject?
      20   7.6%  92.0%       21   8.0% String#==
      10   3.8%  95.8%       10   3.8% garbage_collector
       5   1.9%  97.7%        5   1.9% Symbol#==
       2   0.8%  98.5%        2   0.8% Kernel#class
       1   0.4%  98.9%      251  95.4% AccessGranted::Role#relevant_permissions
       1   0.4%  99.2%        1   0.4% Enumerable#detect
       1   0.4%  99.6%      253  96.2% Integer#times
       1   0.4% 100.0%        1   0.4% Kernel#respond_to_missing?
       0   0.0% 100.0%      252  95.8% AccessGranted::Role#can?
       0   0.0% 100.0%      253  96.2% Benchmark#measure
       0   0.0% 100.0%      253  96.2% Benchmark.measure

After

Total: 78 samples
      29  37.2%  37.2%       48  61.5% AccessGranted::Permission#matches_subject?
      23  29.5%  66.7%       71  91.0% AccessGranted::Role#relevant_permissions
      14  17.9%  84.6%       17  21.8% String#==
       6   7.7%  92.3%        6   7.7% garbage_collector
       3   3.8%  96.2%        3   3.8% Kernel#respond_to_missing?
       2   2.6%  98.7%        2   2.6% Kernel#class
       1   1.3% 100.0%       72  92.3% AccessGranted::Role#can?
       0   0.0% 100.0%       72  92.3% Benchmark#measure
       0   0.0% 100.0%       72  92.3% Benchmark.measure
       0   0.0% 100.0%       72  92.3% Integer#times

code:

require 'bundler'
Bundler.setup
require_relative 'lib/access_granted'
require 'benchmark'

role = AccessGranted::Role.new 'test', 0

stubs = [:edit, :create, :manage, :delete]
names = ('A'..'D').to_a

module TestPool
end

require 'perftools'
measurement = nil
PerfTools::CpuProfiler.start("/tmp/da_bench") do
  measurement = Benchmark.measure do
    names.permutation.each do |perm|
      name = perm.join
      TestPool.const_set name, Struct.new(:nvm)
      stubs.each do |stub|
        role.can stub, name
      end
    end

    puts TestPool.constants.count * stubs.size

    query = TestPool::DCBA.new
    100000.times { role.can? :create, query }
  end
end

puts measurement