Upgrade to Pro — share decks privately, control downloads, hide ads and more …

高度なコード

Avatar for Aaron Patterson Aaron Patterson
September 22, 2014

 高度なコード

Avatar for Aaron Patterson

Aaron Patterson

September 22, 2014
Tweet

More Decks by Aaron Patterson

Other Decks in Technology

Transcript

  1. ετϦʔϛϯά class Stream def each loop { yield "hello world\n"

    } end end $ def call(env) [200, {}, Stream.new] end R ack 1.x
  2. benchmark/ips require 'benchmark/ips' require 'set' $ list = ('a'..'zzzz').to_a set

    = Set.new list $ Benchmark.ips do |x| x.report("set access") { set.include? "foo" } $ x.report("ary access") { list.include? "foo" } end G EM
  3. ग़ྗ Calculating ------------------------------------- set access 68622 i/100ms ary access 395

    i/100ms ------------------------------------------------- set access 3047175.3 (±12.7%) i/s - 14959596 in 5.018692s ary access 3899.2 (±7.1%) i/s - 19750 in 5.096118s ߹ ܭ IPS
  4. Ωϟογϡͷςετ cache1 = Cache1.new cache2 = Cache2.new $ cache1["x"] =

    Object.new cache2["x"] = Object.new $ Benchmark.ips do |x| x.report("cache1") { cache1["x"] } x.report("cache2") { cache2["x"] } end
  5. ࣮ߦͷάϥϑ 10,000 ܁Γฦ࣌ؒ͢ (seconds) 0.01 0.1 1 10 100 ΩϟογϡɹαΠζ

    10 elements 100 elements 1000 elements 100000 elements Ωϟογϡ 1 Ωϟογϡ 2
  6. Cacheͷ࣮૷ class Cache1 def initialize @cache = {} end def

    [] k; @cache[k]; end def []= k,v; @cache[k] = v; end end $ class Cache2 def initialize @cache = [] end def [] k; x, = @cache.assoc(k); x; end def []= k,v; @cache << [k, v]; end end ఆ਺ ઢܗ
  7. Sec /100k calls 9.5 9.7 9.9 10.1 10.3 1 2

    3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 link_to
  8. ௕͞ΛมԽ class MyTest routes = ActionDispatch::Routing::RouteSet.new link = N.times.map(&:to_s).join '/'

    $ routes.draw { get "/#{link}/:id", :as => :article, :controller => :articles, :action => :show } end 10, 100, 1000
  9. ඵ / 10ສճͷݺͼग़͠ 9 10.5 12 13.5 15 1 2

    3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 link_to
  10. Request Benchmark task :allocated_objects do app = Ko1TestApp::Application.instance app.app do_test_task(app)

    env = rackenv "/books/new" do_test_task(app, env.dup) before = GC.stat :total_allocated_object TEST_CNT.times { do_test_task(app, env.dup) } after = GC.stat :total_allocated_object puts (after - before) / TEST_CNT end "/books/new"
  11. Request Benchmark task :allocated_objects do app = Ko1TestApp::Application.instance app.app do_test_task(app)

    env = rackenv "/books/new" do_test_task(app, env.dup) before = GC.stat :total_allocated_object TEST_CNT.times { do_test_task(app, env.dup) } after = GC.stat :total_allocated_object puts (after - before) / TEST_CNT end
  12. Request Benchmark task :allocated_objects do app = Ko1TestApp::Application.instance app.app do_test_task(app)

    env = rackenv "/books/new" do_test_task(app, env.dup) before = GC.stat :total_allocated_object TEST_CNT.times { do_test_task(app, env.dup) } after = GC.stat :total_allocated_object puts (after - before) / TEST_CNT end
  13. ྫ ObjectSpace::AllocationTracer.trace do 1000.times { ["foo", {}] } end $

    ObjectSpace::AllocationTracer.allocated_count_table
  14. TOTAL (pct) SAMPLES (pct) FRAME 813 (9.5%) 813 (9.5%) ActiveSupport::SafeBuffer#initialize

    699 (8.1%) 350 (4.1%) block in ActiveRecord::Read#read_attribute 486 (5.7%) 298 (3.5%) ActionController::UrlFor#url_options 670 (7.8%) 274 (3.2%) ActionDispatch::Journey::Format#evaluate 773 (9.0%) 253 (2.9%) ActionDispatch#parameterize_args 1172 (13.6%) 220 (2.6%) ActiveRecord::Persistence#instantiate 213 (2.5%) 213 (2.5%) block in SQLite3::Statement#each 208 (2.4%) 208 (2.4%) ActiveSupport::SafeBuffer#html_safe? 204 (2.4%) 204 (2.4%) ActionDispatch::UrlFor#routes_generation? 245 (2.9%) 191 (2.2%) block (2 levels) in Class#class_attribute
  15. Tag Options def tag_option(key, value, escape) if value.is_a?(Array) value =

    escape ? safe_join(value, " ") : value.join(" ") else value = escape ? ERB::Util.h(value) : value end %(#{key}="#{value}") end
  16. Ordinary String >> x = "foo" => "foo" >> x.class

    => String >> x.html_safe? => false
  17. SafeBuffer >> x = "foo" => "foo" >> y =

    x.html_safe => "foo" >> y.class => ActiveSupport::SafeBuffer >> y.html_safe? => true
  18. ERB::Utils.h def html_escape(s) s = s.to_s if s.html_safe? s else

    s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE).html_safe end end
  19. Tag Options def tag_option(key, value, escape) if value.is_a?(Array) value =

    escape ? safe_join(value, " ") : value.join(" ") else value = escape ? ERB::Util.h(value) : value end %(#{key}="#{value}") end
  20. Extract Method def unwrapped_html_escape(s) # :nodoc: s = s.to_s if

    s.html_safe? s else s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE) end end $ def html_escape(s) unwrapped_html_escape(s).html_safe end
  21. Update Callers def tag_option(key, value, escape) if value.is_a?(Array) value =

    escape ? safe_join(value, " ") : value.join(" ") else value = escape ? ERB::Util.unwrapped_html_escape(value) : value end %(#{key}="#{value}") end
  22. Compiled Template @output_buffer = output_buffer || ActionView::OutputBuffer.new;@output_buffer.safe_append='<h1>Listing books</h1> $ <table>

    <thead> <tr> <th>Name</th> <th colspan="3"></th> </tr> </thead> $ <tbody> '.freeze; @books.each do |book| @output_buffer.safe_append=' <tr> <td>'.freeze;@output_buffer.append=( book.name );@output_buffer.safe_append='</td> <td>'.freeze;@output_buffer.append=( link_to 'Show', book );@output_buffer.safe_append='</ td> </tr> '.freeze; end @output_buffer.safe_append=' </tbody> </table> $ <br>
  23. Allocations Per Request 0 275 550 825 1100 T_STRING T_ARRAY

    T_HASH T_NODE T_DATA OTHER 4-0-stable 4-1-stable master