Skip to content

Conversation

@k0kubun
Copy link
Member

@k0kubun k0kubun commented Jan 6, 2023

This PR adds Ruby stats to the harness created in #158.

It seems useful to know about Ruby call stats as well when we discuss method inlining implementation.

Example

activerecord

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/activerecord/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
Command: bundle check 2> /dev/null || bundle install
The Gemfile's dependencies are satisfied
Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
-- create_table(:posts, {:force=>true})
   -> 0.0031s
itr #1: 1237ms
Top 10 block calls by C methods (100.0% of all 52000 calls):
   22000 (42.3%) Array#each
   10000 (19.2%) Hash#each_key
    6000 (11.5%) Array#map
    4000 ( 7.7%) #<Class:Thread>#handle_interrupt
    2000 ( 3.8%) Kernel#loop
    2000 ( 3.8%) Hash#each
    2000 ( 3.8%) Array#map!
    2000 ( 3.8%) Monitor#synchronize
    1000 ( 1.9%) Integer#times
    1000 ( 1.9%) Hash#select

Top 100 C method calls (93.0% of all 856021 calls):
   87000 (10.2%) Hash#[]
   44000 ( 5.1%) Module#===
   35000 ( 4.1%) Hash#fetch
   25000 ( 2.9%) #<Class:Thread>#current
   25000 ( 2.9%) Class#new
   25000 ( 2.9%) BasicObject#!
   22000 ( 2.6%) Arel::Collectors::Composite#right
   22000 ( 2.6%) Arel::Collectors::Composite#left
   21000 ( 2.5%) String#<<
   21000 ( 2.5%) Kernel#hash
   20000 ( 2.3%) Hash#[]=
   19000 ( 2.2%) Array#empty?
   18001 ( 2.1%) Array#[]
   18000 ( 2.1%) Kernel#is_a?
   17000 ( 2.0%) ActiveRecord::Relation#klass
   17000 ( 2.0%) Array#each
   15003 ( 1.8%) Integer#+
   14000 ( 1.6%) Thread#[]
   12000 ( 1.4%) Arel::Visitors::Visitor#dispatch
   12000 ( 1.4%) Hash#delete
   10000 ( 1.2%) Integer#<
   10000 ( 1.2%) Array#include?
    9000 ( 1.1%) Module#name
    9000 ( 1.1%) Array#any?
    9000 ( 1.1%) BasicObject#initialize
    9000 ( 1.1%) String#-@
    8000 ( 0.9%) String#to_s
    8000 ( 0.9%) Kernel#respond_to?
    7000 ( 0.8%) Class#superclass
    7000 ( 0.8%) ActiveRecord::TableMetadata#klass
    7000 ( 0.8%) Kernel#nil?
    6000 ( 0.7%) Kernel#block_given?
    6000 ( 0.7%) ActiveRecord::PredicateBuilder#table
    6000 ( 0.7%) ActiveModel::Attribute#value_before_type_cast
    6000 ( 0.7%) Array#map
    6000 ( 0.7%) Kernel#dup
    6000 ( 0.7%) Kernel#initialize_dup
    5000 ( 0.6%) Kernel#object_id
    5000 ( 0.6%) Module#==
    5000 ( 0.6%) Hash#initialize_copy
    5000 ( 0.6%) ActiveRecord::Relation::WhereClause#predicates
    5000 ( 0.6%) Arel::Nodes::BindParam#value
    4000 ( 0.5%) Arel::Table#table_alias
    4000 ( 0.5%) Kernel#freeze
    4000 ( 0.5%) #<Class:Process>#pid
    4000 ( 0.5%) Thread#thread_variable_get
    4000 ( 0.5%) Enumerable#each_with_index
    4000 ( 0.5%) Array#map!
    4000 ( 0.5%) Arel::Table#name
    4000 ( 0.5%) ActiveModel::Attribute#type
    4000 ( 0.5%) Arel::Nodes::SelectCore#source
    4000 ( 0.5%) Integer#==
    4000 ( 0.5%) Arel::Nodes::Binary#left
    3001 ( 0.4%) Array#<<
    3000 ( 0.4%) Array#flatten!
    3000 ( 0.4%) Array#+
    3000 ( 0.4%) FalseClass#===
    3000 ( 0.4%) ActiveRecord::Relation#table
    3000 ( 0.4%) TrueClass#===
    3000 ( 0.4%) Array#length
    3000 ( 0.4%) Kernel#initialize_clone
    3000 ( 0.4%) Symbol#to_s
    3000 ( 0.4%) Struct#initialize
    3000 ( 0.4%) #<Class:#<Class:0x0000000107a424e8>>#new
    3000 ( 0.4%) BasicObject#==
    3000 ( 0.4%) BasicObject#!=
    3000 ( 0.4%) Arel::Nodes::SelectStatement#orders
    3000 ( 0.4%) Hash#each_key
    2001 ( 0.2%) Integer#>
    2000 ( 0.2%) Arel::Nodes::SelectCore#projections
    2000 ( 0.2%) NilClass#nil?
    2000 ( 0.2%) ActiveRecord::ConnectionAdapters::AbstractAdapter#visitor
    2000 ( 0.2%) Arel::Nodes::SelectStatement#offset
    2000 ( 0.2%) Hash#each
    2000 ( 0.2%) Enumerable#map
    2000 ( 0.2%) Arel::Nodes::Binary#right
    2000 ( 0.2%) Integer#<=>
    2000 ( 0.2%) Arel::Nodes::Unary#expr
    2000 ( 0.2%) Array#first
    2000 ( 0.2%) NilClass#===
    2000 ( 0.2%) Hash#empty?
    2000 ( 0.2%) SQLite3::Statement#bind_param
    2000 ( 0.2%) SQLite3::Database#encoding
    2000 ( 0.2%) SQLite3::Statement#done?
    2000 ( 0.2%) Module#<=
    2000 ( 0.2%) Kernel#instance_variable_defined?
    2000 ( 0.2%) SQLite3::Statement#step
    2000 ( 0.2%) Enumerable#flat_map
    2000 ( 0.2%) ActiveRecord::TableMetadata#types
    2000 ( 0.2%) Array#last
    2000 ( 0.2%) ActiveRecord::Relation#loaded
    2000 ( 0.2%) Array#reject!
    2000 ( 0.2%) Arel::Nodes::SelectStatement#cores
    2000 ( 0.2%) String#include?
    2000 ( 0.2%) Arel::Nodes::SelectCore#wheres
    2000 ( 0.2%) Array#concat
    2000 ( 0.2%) String#initialize
    2000 ( 0.2%) #<Class:Thread>#handle_interrupt
    2000 ( 0.2%) Monitor#synchronize
    2000 ( 0.2%) Symbol#==

Top 100 Ruby method calls (62.5% of all 611005 calls):
   26000 ( 4.3%) Kernel#class
   21000 ( 3.4%) Arel::Collectors::PlainString#<<
   19000 ( 3.1%) Arel::Collectors::Bind#<<
   19000 ( 3.1%) Arel::Collectors::Composite#<<
   12000 ( 2.0%) Arel::Visitors::Visitor#visit
    9000 ( 1.5%) ActiveSupport::PerThreadRegistry#instance
    8000 ( 1.3%) Concurrent::Collection::NonConcurrentMapBackend#[]
    8000 ( 1.3%) Concurrent::Map#[]
    7000 ( 1.1%) ActiveRecord::Scoping::ScopeRegistry#raise_invalid_scope_type!
    6000 ( 1.0%) Arel::Visitors::ToSql#maybe_visit
    6000 ( 1.0%) ActiveRecord::ConnectionHandling#connection_specification_name
    5000 ( 0.8%) ActiveRecord::Relation#already_in_scope?
    5000 ( 0.8%) Arel::Visitors::ToSql#collect_nodes_for
    4000 ( 0.7%) ActiveRecord::ConnectionAdapters::AbstractAdapter#prepared_statements
    4000 ( 0.7%) #<Class:ActiveRecord::Base>#default_connection_handler
    4000 ( 0.7%) ActiveRecord::Scoping::ClassMethods#current_scope=
    4000 ( 0.7%) #<Class:ActiveRecord::Base>#connection_handler
    4000 ( 0.7%) ActiveRecord::Scoping::ScopeRegistry#set_value_for
    4000 ( 0.7%) #<Class:ActiveRecord::Scoping::ScopeRegistry>#set_value_for
    4000 ( 0.7%) #<Class:ActiveRecord::ConnectionAdapters::AbstractAdapter>#quoted_table_names
    4000 ( 0.7%) ActiveRecord::QueryMethods#assert_mutability!
    4000 ( 0.7%) Arel::Visitors::ToSql#quote_table_name
    4000 ( 0.7%) Set#include?
    4000 ( 0.7%) ActiveRecord::ConnectionAdapters::SQLite3::Quoting#quote_table_name
    4000 ( 0.7%) ActiveRecord::ConnectionAdapters::AbstractAdapter#prepared_statements_disabled_cache
    3000 ( 0.5%) ActiveRecord::Scoping::ClassMethods#current_scope
    3000 ( 0.5%) ActiveModel::Attribute#initialize
    3000 ( 0.5%) ActiveRecord::Relation#reset
    3000 ( 0.5%) ActiveRecord::QueryMethods#limit_value
    3000 ( 0.5%) ActiveRecord::Relation#initialize_copy
    3000 ( 0.5%) #<Class:ActiveRecord::Base>#attribute_aliases
    3000 ( 0.5%) Kernel#clone
    3000 ( 0.5%) ActiveRecord::ConnectionAdapters::ConnectionPool#current_thread
    3000 ( 0.5%) ActiveRecord::ConnectionAdapters::ConnectionPool#connection
    3000 ( 0.5%) Concurrent::Collection::NonConcurrentMapBackend#get_or_default
    3000 ( 0.5%) Concurrent::Map#fetch
    3000 ( 0.5%) ActiveRecord::ConnectionAdapters::ConnectionHandler#owner_to_pool
    3000 ( 0.5%) ActiveRecord::ConnectionAdapters::ConnectionHandler#retrieve_connection_pool
    3000 ( 0.5%) ActiveRecord::ConnectionAdapters::ConnectionHandler#retrieve_connection
    3000 ( 0.5%) ActiveRecord::ConnectionHandling#retrieve_connection
    3000 ( 0.5%) ActiveRecord::ConnectionHandling#connection
    3000 ( 0.5%) ActiveRecord::ModelSchema::ClassMethods#load_schema
    3000 ( 0.5%) Object#blank?
    3000 ( 0.5%) ActiveRecord::ModelSchema::ClassMethods#attribute_types
    3000 ( 0.5%) ActiveRecord::SpawnMethods#spawn
    3000 ( 0.5%) Arel::Table#[]
    3000 ( 0.5%) ActiveRecord::AttributeMethods::PrimaryKey::ClassMethods#primary_key
    3000 ( 0.5%) ActiveRecord::QueryMethods#order_values
    3000 ( 0.5%) ActiveRecord::Scoping::ScopeRegistry#value_for
    3000 ( 0.5%) ActiveRecord::QueryMethods#where_clause
    3000 ( 0.5%) ActiveModel::Attribute#value
    3000 ( 0.5%) ActiveRecord::QueryMethods#includes_values
    3000 ( 0.5%) #<Class:ActiveRecord::Scoping::ScopeRegistry>#value_for
    3000 ( 0.5%) Arel::Visitors::ToSql#quote_column_name
    3000 ( 0.5%) Arel::Visitors::ToSql#visit_Arel_Attributes_Attribute
    3000 ( 0.5%) Arel::Visitors::ToSql#inject_join
    3000 ( 0.5%) ActiveRecord::ModelSchema::ClassMethods#schema_loaded?
    3000 ( 0.5%) ActiveRecord::ConnectionAdapters::ConnectionPool#connection_cache_key
    2000 ( 0.3%) ActiveSupport::Notifications::Fanout::Subscribers::Evented#finish
    2000 ( 0.3%) Arel::Collectors::SQLString#add_bind
    2000 ( 0.3%) #<Class:ActiveRecord::Base>#implicit_order_column
    2000 ( 0.3%) Arel::Collectors::Composite#add_bind
    2000 ( 0.3%) ActiveRecord::Delegation#primary_key
    2000 ( 0.3%) Post::GeneratedRelationMethods#implicit_order_column
    2000 ( 0.3%) ActiveRecord::Core::ClassMethods#arel_attribute
    2000 ( 0.3%) ActiveModel::Type::Value#cast
    2000 ( 0.3%) #<Class:ActiveRecord::Base>#__callbacks
    2000 ( 0.3%) Arel::Nodes::BindParam#initialize
    2000 ( 0.3%) ActiveRecord::Relation#_scoping
    2000 ( 0.3%) ActiveRecord::ConnectionAdapters::SQLite3::Quoting#quote_column_name
    2000 ( 0.3%) ActiveSupport::Callbacks#run_callbacks
    2000 ( 0.3%) MonitorMixin#mon_synchronize
    2000 ( 0.3%) ActiveRecord::Relation::WhereClause#initialize
    2000 ( 0.3%) Arel::Nodes::Binary#initialize
    2000 ( 0.3%) #<Class:ActiveRecord::ConnectionAdapters::AbstractAdapter>#quoted_column_names
    2000 ( 0.3%) ActiveRecord::Relation::WhereClause#empty?
    2000 ( 0.3%) Arel::Visitors::ToSql#visit_Arel_Nodes_BindParam
    2000 ( 0.3%) ActiveRecord::ModelSchema::ClassMethods#inheritance_column
    2000 ( 0.3%) #<Class:ActiveRecord::Base>#logger
    2000 ( 0.3%) ActiveRecord::LogSubscriber#logger
    2000 ( 0.3%) ActiveRecord::Relation#eager_loading?
    2000 ( 0.3%) ActiveSupport::Notifications::Fanout::Subscribers::Evented#start
    2000 ( 0.3%) ActiveSupport::Notifications::Fanout#listeners_for
    2000 ( 0.3%) ActiveSupport::Notifications::Instrumenter#start
    2000 ( 0.3%) Arel::Nodes::Unary#initialize
    2000 ( 0.3%) ActiveRecord::QueryMethods#offset_value
    2000 ( 0.3%) ActiveRecord::TableMetadata#type
    2000 ( 0.3%) ActiveRecord::ModelSchema::ClassMethods#type_for_attribute
    2000 ( 0.3%) ActiveModel::Attribute#value_for_database
    2000 ( 0.3%) #<Class:Post(id: integer, title: string, body: string, type_name: string, key: string, upvotes: integer, author_id: integer, created_at: datetime, updated_at: datetime)>#default_scope_override
    2000 ( 0.3%) ActiveRecord::ConnectionAdapters::Quoting#type_cast
    2000 ( 0.3%) ActiveRecord::Relation::QueryAttribute#value_for_database
    2000 ( 0.3%) ActiveRecord::ConnectionAdapters::SQLite3::Quoting#_type_cast
    2000 ( 0.3%) ActiveSupport::Callbacks::CallbackChain#empty?
    2000 ( 0.3%) Symbol#to_sym
    2000 ( 0.3%) ActiveRecord::Base#__callbacks
    2000 ( 0.3%) ActiveRecord::Relation#scoping
    2000 ( 0.3%) ActiveSupport::Notifications::Instrumenter#finish_with_state
    2000 ( 0.3%) ActiveSupport::Notifications::Fanout#finish
    2000 ( 0.3%) Arel::Collectors::Bind#add_bind

hexapdf

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/hexapdf/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
Command: bundle check 2> /dev/null || bundle install
The Gemfile's dependencies are satisfied
Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
itr #1: 47861ms
Top 29 block calls by C methods (100.0% of all 3536312 calls):
 1343368 (38.0%) Array#each
 1062997 (30.1%) Array#sum
  697504 (19.7%) Array#map!
  209898 ( 5.9%) Array#bsearch_index
   81798 ( 2.3%) Hash#each
   39090 ( 1.1%) Array#each_index
   29288 ( 0.8%) Array#select
   17092 ( 0.5%) Array#sort!
   11480 ( 0.3%) Integer#downto
    9818 ( 0.3%) Hash#each_key
    9029 ( 0.3%) Array#map
    6539 ( 0.2%) Hash#each_value
    5726 ( 0.2%) Array#any?
    3281 ( 0.1%) Fiber#resume
    2388 ( 0.1%) Integer#times
    1628 ( 0.0%) Array#reject!
    1627 ( 0.0%) Array#select!
    1626 ( 0.0%) Array#rindex
     840 ( 0.0%) Hash#[]
     820 ( 0.0%) Array#delete_if
     224 ( 0.0%) Range#each
     223 ( 0.0%) Integer#upto
      14 ( 0.0%) Module#module_eval
       5 ( 0.0%) Hash#delete
       4 ( 0.0%) #<Class:IO>#open
       2 ( 0.0%) Hash#transform_values
       1 ( 0.0%) #<Class:Struct>#new
       1 ( 0.0%) Enumerable#reverse_each
       1 ( 0.0%) Module#refine

Top 100 C method calls (97.9% of all 45380570 calls):
 3239193 ( 7.1%) Hash#[]
 2491687 ( 5.5%) HexaPDF::Layout::TextFragment#style
 2377855 ( 5.2%) Kernel#kind_of?
 2254003 ( 5.0%) Integer#+
 1703849 ( 3.8%) Array#[]
 1514209 ( 3.3%) HexaPDF::Layout::TextFragment#items
 1421062 ( 3.1%) Kernel#hash
 1156732 ( 2.5%) Float#+
 1149130 ( 2.5%) Integer#-
 1127352 ( 2.5%) BasicObject#!
 1115692 ( 2.5%) Array#<<
 1091811 ( 2.4%) Geom2D::Point#x
  964984 ( 2.1%) Symbol#==
  932422 ( 2.1%) HexaPDF::Font::Type1Wrapper::Glyph#str
  822355 ( 1.8%) String#<<
  811969 ( 1.8%) Geom2D::Algorithms::PolygonOperation::SweepEvent#point
  799739 ( 1.8%) Geom2D::Point#y
  768030 ( 1.7%) Float#-
  697434 ( 1.5%) Regexp#match?
  677772 ( 1.5%) Integer#*
  661586 ( 1.5%) Array#size
  659622 ( 1.5%) HexaPDF::Content::Canvas#graphics_object
  626447 ( 1.4%) HexaPDF::Font::Type1Wrapper::Glyph#name
  616061 ( 1.4%) Integer#==
  615052 ( 1.4%) BasicObject#==
  601079 ( 1.3%) Class#new
  536154 ( 1.2%) #<Class:Geom2D::Utils>#precision
  525446 ( 1.2%) Float#<=
  514064 ( 1.1%) Integer#<
  481495 ( 1.1%) BasicObject#!=
  478456 ( 1.1%) Array#empty?
  450788 ( 1.0%) HexaPDF::Content::Canvas#graphics_state
  433155 ( 1.0%) Array#each
  426810 ( 0.9%) Float#<
  361961 ( 0.8%) Array#clear
  356875 ( 0.8%) HexaPDF::Object#data
  336821 ( 0.7%) HexaPDF::Layout::TextLayouter::Box#item
  303578 ( 0.7%) Kernel#instance_of?
  287243 ( 0.6%) HexaPDF::PDFData#value
  268250 ( 0.6%) Array#sum
  252165 ( 0.6%) Array#last
  248834 ( 0.5%) Kernel#initialize_dup
  248834 ( 0.5%) Kernel#dup
  243620 ( 0.5%) Float#>
  236755 ( 0.5%) Geom2D::Algorithms::PolygonOperation::SweepEvent#other_event
  234718 ( 0.5%) HexaPDF::Layout::TextLayouter#style
  224138 ( 0.5%) Kernel#nil?
  220463 ( 0.5%) Geom2D::Segment#start_point
  217254 ( 0.5%) HexaPDF::Layout::Line#x_offset=
  217254 ( 0.5%) HexaPDF::Content::GraphicsState#tlm
  217254 ( 0.5%) HexaPDF::Layout::Line#x_offset
  217167 ( 0.5%) Array#concat
  204662 ( 0.5%) Integer#/
  195741 ( 0.4%) Integer#>
  195261 ( 0.4%) Geom2D::Algorithms::PolygonOperation::SweepEvent#left
  190881 ( 0.4%) Array#[]=
  187015 ( 0.4%) Array#push
  165143 ( 0.4%) Geom2D::Segment#end_point
  163640 ( 0.4%) Float#*
  160732 ( 0.4%) Integer#<=>
  146464 ( 0.3%) HexaPDF::Layout::Line#y_offset
  144836 ( 0.3%) HexaPDF::Content::GraphicsState#leading
  144835 ( 0.3%) HexaPDF::Layout::Style::LineSpacing#value
  144835 ( 0.3%) HexaPDF::Layout::Style::LineSpacing#type
  140717 ( 0.3%) Array#length
  139550 ( 0.3%) Float#/
  139146 ( 0.3%) Float#<=>
  135569 ( 0.3%) String#==
  135303 ( 0.3%) Kernel#freeze
  134370 ( 0.3%) Module#===
  126941 ( 0.3%) Integer#>=
  125101 ( 0.3%) Kernel#initialize_copy
  124974 ( 0.3%) HexaPDF::Layout::TextLayouter::Glue#item
  124466 ( 0.3%) Geom2D::Algorithms::PolygonOperation::SweepEvent#polygon_type
   99694 ( 0.2%) NilClass#nil?
   94196 ( 0.2%) HexaPDF::Layout::Line#items
   74046 ( 0.2%) HexaPDF::Content::GraphicsState#tm=
   74046 ( 0.2%) Enumerable#each_with_index
   73232 ( 0.2%) HexaPDF::Layout::Line#y_offset=
   72670 ( 0.2%) String#initialize_copy
   72625 ( 0.2%) String#b
   72418 ( 0.2%) HexaPDF::Content::TransformationMatrix#e
   72418 ( 0.2%) HexaPDF::Content::TransformationMatrix#f
   72201 ( 0.2%) Hash#[]=
   71604 ( 0.2%) HexaPDF::Content::Canvas#operators
   71027 ( 0.2%) String#gsub!
   70971 ( 0.2%) String#encoding
   66479 ( 0.1%) Hash#key?
   65592 ( 0.1%) Integer#<=
   51058 ( 0.1%) Array#initialize_copy
   51055 ( 0.1%) HexaPDF::Layout::TextFragment#items=
   47287 ( 0.1%) Kernel#block_given?
   47132 ( 0.1%) String#getbyte
   45558 ( 0.1%) Geom2D::BoundingBox#max_x
   45556 ( 0.1%) Geom2D::Algorithms::PolygonOperation::SweepEvent#edge_type
   44746 ( 0.1%) Geom2D::Algorithms::PolygonOperation::SweepEvent#other_in_out
   43932 ( 0.1%) Array#insert
   43932 ( 0.1%) Array#bsearch_index
   39295 ( 0.1%) HexaPDF::PDFData#oid
   35958 ( 0.1%) HexaPDF::Font::InvalidGlyph#str

Top 100 Ruby method calls (93.6% of all 12860877 calls):
 1062997 ( 8.3%) HexaPDF::Layout::Style#scaled_item_width
  857707 ( 6.7%) HexaPDF::Layout::TextFragment#width
  626061 ( 4.9%) HexaPDF::Font::Type1Wrapper#encode
  424713 ( 3.3%) Float#abs
  329508 ( 2.6%) Integer#abs
  308867 ( 2.4%) HexaPDF::Layout::TextLayouter::Box#type
  302472 ( 2.4%) Kernel#class
  299400 ( 2.3%) Geom2D::Utils#float_compare
  262733 ( 2.0%) HexaPDF::Object#value
  223130 ( 1.7%) HexaPDF::Content::Canvas#raise_unless_at_page_description_level_or_in_text
  215804 ( 1.7%) HexaPDF::Content::Canvas#begin_text
  214722 ( 1.7%) HexaPDF::Layout::Line#add
  211534 ( 1.6%) Geom2D::Utils#float_equal
  200076 ( 1.6%) HexaPDF::Layout::TextLayouter::SimpleLineWrapping#add_box_item
  149717 ( 1.2%) HexaPDF::Layout::Line#y_max
  148814 ( 1.2%) HexaPDF::Layout::Style#scaled_y_min
  148814 ( 1.2%) HexaPDF::Layout::TextFragment#y_max
  148814 ( 1.2%) HexaPDF::Layout::TextFragment#y_min
  148814 ( 1.2%) HexaPDF::Layout::Style#scaled_y_max
  148089 ( 1.2%) HexaPDF::Layout::Line#y_min
  146462 ( 1.1%) HexaPDF::Layout::TextFragment#valign
  144836 ( 1.1%) HexaPDF::Layout::Style#line_spacing
  144812 ( 1.1%) #<Class:Geom2D>#Point
  143988 ( 1.1%) HexaPDF::Layout::TextFragment#initialize
  142499 ( 1.1%) HexaPDF::Layout::TextLayouter::Box#initialize
  139134 ( 1.1%) HexaPDF::Layout::TextLayouter::Glue#type
  139088 ( 1.1%) Kernel#frozen?
  139088 ( 1.1%) HexaPDF::Layout::TextFragment#clear_cache
  125638 ( 1.0%) HexaPDF::Layout::TextFragment#height
  125638 ( 1.0%) HexaPDF::Layout::TextLayouter::Box#width
  125638 ( 1.0%) HexaPDF::Layout::TextLayouter::Box#height
  124974 ( 1.0%) HexaPDF::Layout::TextLayouter::SimpleLineWrapping#add_glue_item
  118699 ( 0.9%) HexaPDF::Layout::TextLayouter::SimpleLineWrapping#update_last_breakpoint
  105771 ( 0.8%) Geom2D::Algorithms::PolygonOperation::SweepEvent#process_after?
   93567 ( 0.7%) Geom2D::Point#==
   81711 ( 0.6%) HexaPDF::DictionaryFields::Field#required?
   79300 ( 0.6%) HexaPDF::Dictionary#key?
   77288 ( 0.6%) #<Class:Geom2D::Algorithms>#ccw
   77147 ( 0.6%) HexaPDF::Layout::Line#initialize
   77147 ( 0.6%) HexaPDF::Layout::TextLayouter::SimpleLineWrapping#create_line
   76409 ( 0.6%) HexaPDF::Layout::Line::HeightCalculator#initialize
   76409 ( 0.6%) HexaPDF::Layout::Line::HeightCalculator#reset
   74860 ( 0.6%) HexaPDF::Content::Operator::NoArgumentOperator#serialize
   74860 ( 0.6%) HexaPDF::Content::Canvas#invoke0
   74044 ( 0.6%) HexaPDF::Layout::Line::HeightCalculator#result
   74044 ( 0.6%) HexaPDF::Layout::Line::HeightCalculator#add
   74044 ( 0.6%) HexaPDF::Layout::Line#calculate_y_dimensions
   74044 ( 0.6%) HexaPDF::Layout::Line#height
   74044 ( 0.6%) HexaPDF::Layout::TextLayouter#create_combined_line
   73232 ( 0.6%) HexaPDF::Layout::Style#overlays?
   73232 ( 0.6%) HexaPDF::Layout::Style#underlays?
   73232 ( 0.6%) HexaPDF::Layout::Line#width
   73231 ( 0.6%) HexaPDF::Layout::Style::LineSpacing#gap
   72418 ( 0.6%) HexaPDF::Layout::Style#strikeout?
   72418 ( 0.6%) HexaPDF::Layout::Line#each
   72418 ( 0.6%) HexaPDF::Layout::Style#underline?
   72418 ( 0.6%) HexaPDF::Content::Canvas#show_glyphs_only
   72418 ( 0.6%) HexaPDF::Content::TransformationMatrix#translate
   72418 ( 0.6%) HexaPDF::Content::Operator::MoveText#invoke
   72418 ( 0.6%) HexaPDF::Layout::TextLayouter#horizontal_alignment_offset
   72418 ( 0.6%) HexaPDF::Layout::Style#align
   72418 ( 0.6%) HexaPDF::Layout::TextLayouter::SimpleLineWrapping#reset_after_line_break
   72418 ( 0.6%) HexaPDF::Layout::TextFragment#draw
   72418 ( 0.6%) HexaPDF::Content::Canvas#move_text_cursor
   72418 ( 0.6%) HexaPDF::Layout::TextLayouter#apply_offsets
   71604 ( 0.6%) HexaPDF::Layout::Style::LineSpacing#baseline_distance
   71604 ( 0.6%) HexaPDF::Content::Operator::MoveTextNextLine#invoke
   71604 ( 0.6%) Float#-@
   70971 ( 0.6%) HexaPDF::Serializer#serialize_string
   70968 ( 0.6%) HexaPDF::Content::Canvas#serialize1
   70968 ( 0.6%) HexaPDF::Content::Canvas#raise_unless_font_set
   70968 ( 0.6%) HexaPDF::Content::Operator::ShowText#serialize
   62640 ( 0.5%) Geom2D::Segment#initialize
   48214 ( 0.4%) #<Class:HexaPDF::Dictionary>#field
   45556 ( 0.4%) Geom2D::Algorithms::PolygonOperation::SweepEvent#in_result?
   44113 ( 0.3%) HexaPDF::Object#document
   43932 ( 0.3%) Geom2D::Utils::SortedList#insert
   43158 ( 0.3%) HexaPDF::PDFArray#process_entry
   42344 ( 0.3%) HexaPDF::PDFArray#[]
   39295 ( 0.3%) HexaPDF::Object#oid
   37737 ( 0.3%) HexaPDF::Layout::TextLayouter::Penalty#type
   37528 ( 0.3%) HexaPDF::DictionaryFields::Field#type
   34278 ( 0.3%) HexaPDF::Dictionary#[]
   34170 ( 0.3%) #<Class:Geom2D>#Segment
   34170 ( 0.3%) Geom2D::Algorithms::PolygonOperation::SweepEvent#segment
   30915 ( 0.2%) Geom2D::Utils::SortedList#empty?
   30208 ( 0.2%) HexaPDF::DictionaryFields::Field#convert
   29288 ( 0.2%) Geom2D::Utils::SortedList#push
   29288 ( 0.2%) Geom2D::Algorithms::PolygonOperation::SweepEvent#initialize
   29288 ( 0.2%) Geom2D::Utils::SortedList#pop
   29288 ( 0.2%) Geom2D::Utils::SortedList#last
   27664 ( 0.2%) Geom2D::Point#initialize
   26034 ( 0.2%) Geom2D::Algorithms::PolygonOperation::SweepEvent#vertical?
   26032 ( 0.2%) Geom2D::Algorithms::PolygonOperation#compute_event_fields
   21967 ( 0.2%) Geom2D::Algorithms::PolygonOperation::SweepEvent#below?
   21483 ( 0.2%) HexaPDF::Serializer#__serialize
   20414 ( 0.2%) HexaPDF::Object#indirect?
   20339 ( 0.2%) Geom2D::Algorithms::PolygonOperation::SweepEvent#segment_below?
   17934 ( 0.1%) #<Class:HexaPDF::DictionaryFields::DictionaryConverter>#convert
   17899 ( 0.1%) Geom2D::Algorithms::PolygonOperation::SweepEvent#above?

liquid-render

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/liquid-render/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
itr #1: 2153ms
Top 10 block calls by C methods (100.0% of all 136409 calls):
   57285 (42.0%) Array#each
   35200 (25.8%) Array#find_index
   30800 (22.6%) Array#each_index
    6160 ( 4.5%) Array#map
    4700 ( 3.4%) Kernel#loop
    1760 ( 1.3%) Hash#reject
     420 ( 0.3%) Hash#each
      57 ( 0.0%) Hash#each_key
      20 ( 0.0%) Integer#times
       7 ( 0.0%) Array#select

Top 100 C method calls (99.9% of all 1626030 calls):
  241047 (14.8%) Kernel#respond_to?
  143341 ( 8.8%) Array#[]
  114997 ( 7.1%) Kernel#is_a?
  103104 ( 6.3%) Hash#[]
   98563 ( 6.1%) Integer#+
   88440 ( 5.4%) Liquid::Context#resource_limits
   81667 ( 5.0%) Kernel#instance_of?
   71220 ( 4.4%) BasicObject#!
   70660 ( 4.3%) String#<<
   61177 ( 3.8%) Hash#key?
   58861 ( 3.6%) NilClass#nil?
   57206 ( 3.5%) Array#each
   48640 ( 3.0%) String#to_s
   46361 ( 2.9%) Kernel#nil?
   42700 ( 2.6%) Array#empty?
   33860 ( 2.1%) Array#each_index
   33580 ( 2.1%) Array#find_index
   30060 ( 1.8%) Liquid::Context#global_filter
   19707 ( 1.2%) Array#map
   11960 ( 0.7%) Array#length
   11880 ( 0.7%) Integer#==
    8158 ( 0.5%) Hash#[]=
    7760 ( 0.5%) Module#===
    7200 ( 0.4%) BasicObject#!=
    6100 ( 0.4%) Liquid::Context#registers
    5340 ( 0.3%) Integer#to_s
    4700 ( 0.3%) Kernel#loop
    4700 ( 0.3%) Liquid::Condition#operator
    4700 ( 0.3%) Liquid::Condition#right
    4700 ( 0.3%) Liquid::Condition#left
    4700 ( 0.3%) Liquid::Condition#child_relation
    4500 ( 0.3%) Integer#&
    4500 ( 0.3%) Integer#<<
    4080 ( 0.3%) Liquid::Context#strict_variables
    3825 ( 0.2%) Class#new
    3620 ( 0.2%) Integer#<=
    3360 ( 0.2%) Kernel#format
    3360 ( 0.2%) Integer#/
    3161 ( 0.2%) Integer#>
    3160 ( 0.2%) String#==
    3101 ( 0.2%) Array#<<
    2760 ( 0.2%) Array#shift
    2517 ( 0.2%) Array#last
    2480 ( 0.2%) #<Class:Regexp>#last_match
    2400 ( 0.1%) Liquid::Context#exception_renderer=
    2400 ( 0.1%) Kernel#freeze
    2380 ( 0.1%) BasicObject#==
    2340 ( 0.1%) Liquid::Condition#attachment
    2300 ( 0.1%) Array#first
    1660 ( 0.1%) String#=~
    1640 ( 0.1%) String#length
    1640 ( 0.1%) Regexp#===
    1521 ( 0.1%) Array#size
    1500 ( 0.1%) CGI::Escape#escapeHTML
    1460 ( 0.1%) String#+@
    1460 ( 0.1%) Integer#-
    1340 ( 0.1%) Liquid::Drop#context=
    1280 ( 0.1%) Array#unshift
    1280 ( 0.1%) Liquid::Context#base_scope_depth
    1280 ( 0.1%) Integer#<
    1220 ( 0.1%) String#gsub!
    1200 ( 0.1%) #<Class:Liquid::Template>#default_exception_renderer
    1200 ( 0.1%) Liquid::Context#errors
    1200 ( 0.1%) Array#flatten!
    1200 ( 0.1%) Hash#each_key
    1200 ( 0.1%) Enumerable#flat_map
    1120 ( 0.1%) Array#hash
    1120 ( 0.1%) String#empty?
    1119 ( 0.1%) Array#eql?
    1100 ( 0.1%) Array#push
    1100 ( 0.1%) Array#pop
     900 ( 0.1%) String#concat
     860 ( 0.1%) String#gsub
     800 ( 0.0%) String#===
     780 ( 0.0%) String#bytesize
     720 ( 0.0%) Liquid::Context#strict_filters
     720 ( 0.0%) Regexp#match
     700 ( 0.0%) String#[]
     561 ( 0.0%) Array#join
     560 ( 0.0%) Time#strftime
     560 ( 0.0%) String#downcase
     480 ( 0.0%) MatchData#begin
     480 ( 0.0%) MatchData#end
     480 ( 0.0%) String#[]=
     460 ( 0.0%) String#split
     280 ( 0.0%) String#strip
     280 ( 0.0%) Integer#to_f
     280 ( 0.0%) NilClass#===
     280 ( 0.0%) String#scan
     240 ( 0.0%) Kernel#block_given?
     240 ( 0.0%) Time#getlocal
     240 ( 0.0%) #<Class:Time>#local
     240 ( 0.0%) #<Class:Date>#_parse
     201 ( 0.0%) Integer#>=
     141 ( 0.0%) Integer#*
     140 ( 0.0%) Float#/
     140 ( 0.0%) Array#reverse!
     140 ( 0.0%) String#+
     140 ( 0.0%) Array#include?
     140 ( 0.0%) Float#ceil

Top 100 Ruby method calls (99.8% of all 911281 calls):
  115120 (12.6%) Liquid::Context#evaluate
   80520 ( 8.8%) Liquid::ResourceLimits#increment_write_score
   71457 ( 7.8%) Liquid::Context#lookup_and_evaluate
   40280 ( 4.4%) Liquid::Context#interrupt?
   37420 ( 4.1%) #<Class:Liquid::BlockBody>#render_node
   37420 ( 4.1%) Liquid::BlockBody#render_node
   33580 ( 3.7%) Liquid::VariableLookup#evaluate
   33580 ( 3.7%) Liquid::Context#find_variable
   32800 ( 3.6%) String#to_liquid
   30060 ( 3.3%) Liquid::Context#apply_global_filter
   30060 ( 3.3%) Liquid::Variable#render
   30000 ( 3.3%) Liquid::Variable#render_to_output_buffer
   26300 ( 2.9%) Hash#to_liquid
   23247 ( 2.6%) Kernel#class
   21047 ( 2.3%) Set#include?
   19713 ( 2.2%) #<Class:Liquid::StrainerTemplate>#filter_methods
   19707 ( 2.2%) #<Class:Liquid::StrainerTemplate>#invokable?
   19700 ( 2.2%) Liquid::Context#invoke
   19700 ( 2.2%) Liquid::Variable#evaluate_filter_expressions
   19700 ( 2.2%) Liquid::Context#strainer
   19700 ( 2.2%) Liquid::StrainerTemplate#invoke
   14080 ( 1.5%) Liquid::Context#try_variable_find_in_environments
   11240 ( 1.2%) Numeric#to_liquid
    6660 ( 0.7%) Liquid::BlockBody#render_to_output_buffer
    6660 ( 0.7%) Liquid::ResourceLimits#increment_render_score
    6660 ( 0.7%) Kernel#frozen?
    4900 ( 0.5%) NilClass#to_liquid
    4700 ( 0.5%) Liquid::Condition#interpret_condition
    4700 ( 0.5%) Liquid::If#render_to_output_buffer
    4700 ( 0.5%) Liquid::Condition#evaluate
    4260 ( 0.5%) Liquid::Context#[]=
    2860 ( 0.3%) Liquid::ForloopDrop#increment!
    2640 ( 0.3%) ShopFilter#asset_url
    2460 ( 0.3%) #<Class:Liquid::Utils>#slice_collection
    2460 ( 0.3%) #<Class:Liquid::Utils>#slice_collection_using_each
    2420 ( 0.3%) Liquid::For#render_to_output_buffer
    2420 ( 0.3%) Liquid::For#collection_segment
    2400 ( 0.3%) ShopFilter#script_tag
    2200 ( 0.2%) #<Class:Liquid::Condition>#operators
    1860 ( 0.2%) MoneyFilter#money
    1720 ( 0.2%) Liquid::Condition#equal_variables
    1700 ( 0.2%) Array#to_liquid
    1660 ( 0.2%) ShopFilter#stylesheet_tag
    1500 ( 0.2%) #<Class:Liquid::Utils>#to_integer
    1500 ( 0.2%) Liquid::StandardFilters#escape
    1500 ( 0.2%) MoneyFilter#money_with_currency
    1340 ( 0.1%) Liquid::Drop#to_liquid
    1340 ( 0.1%) Liquid::Drop#key?
    1340 ( 0.1%) ShopFilter#global_asset_url
    1340 ( 0.1%) #<Class:Liquid::Drop>#invokable_methods
    1340 ( 0.1%) Liquid::Drop#invoke_drop
    1340 ( 0.1%) #<Class:Liquid::Drop>#invokable?
    1340 ( 0.1%) Liquid::ForloopDrop#first
    1320 ( 0.1%) Liquid::For#render_else
    1280 ( 0.1%) Liquid::Context#overflow?
    1280 ( 0.1%) Liquid::Context#pop
    1280 ( 0.1%) Liquid::Context#stack
    1280 ( 0.1%) Liquid::Context#push
    1280 ( 0.1%) Liquid::Context#check_overflow
    1240 ( 0.1%) ShopFilter#product_img_url
    1200 ( 0.1%) Liquid::ResourceLimits#reset
    1200 ( 0.1%) Liquid::Template#with_profiling
    1200 ( 0.1%) Liquid::Template#instance_assigns
    1200 ( 0.1%) Liquid::Document#render_to_output_buffer
    1200 ( 0.1%) Liquid::Context#initialize
    1200 ( 0.1%) Liquid::Template#registers
    1200 ( 0.1%) Liquid::Template#render!
    1200 ( 0.1%) Liquid::Context#squash_instance_assigns_with_environments
    1200 ( 0.1%) Liquid::Template#render
    1200 ( 0.1%) Liquid::Template#assigns
    1180 ( 0.1%) ShopFilter#pluralize
    1120 ( 0.1%) Liquid::StrainerFactory#create
    1120 ( 0.1%) Liquid::StrainerTemplate#initialize
    1120 ( 0.1%) Liquid::StrainerFactory#strainer_class_cache
    1120 ( 0.1%) Liquid::StrainerFactory#strainer_from_cache
    1100 ( 0.1%) Liquid::ForloopDrop#initialize
    1100 ( 0.1%) Liquid::For#render_segment
    1040 ( 0.1%) FalseClass#to_liquid
     900 ( 0.1%) Liquid::Assign#assign_score_of
     860 ( 0.1%) Liquid::StandardFilters#strip_html
     820 ( 0.1%) Liquid::StandardFilters#truncate
     600 ( 0.1%) ShopFilter#shopify_asset_url
     560 ( 0.1%) #<Class:Time>#now
     560 ( 0.1%) #<Class:Liquid::Utils>#to_date
     560 ( 0.1%) Liquid::StandardFilters#date
     540 ( 0.1%) TrueClass#to_liquid
     460 ( 0.1%) Liquid::StandardFilters#truncatewords
     340 ( 0.0%) Liquid::ElseCondition#evaluate
     280 ( 0.0%) Liquid::VariableLookup#initialize
     280 ( 0.0%) Liquid::Context#[]
     280 ( 0.0%) #<Class:Liquid::VariableLookup>#parse
     280 ( 0.0%) #<Class:Liquid::Expression>#parse
     260 ( 0.0%) Liquid::Tag#render_to_output_buffer
     260 ( 0.0%) Liquid::BlockBody#render
     260 ( 0.0%) Liquid::Block#render
     240 ( 0.0%) ShopFilter#link_to
     240 ( 0.0%) #<Class:Time>#make_time
     240 ( 0.0%) #<Class:Time>#parse
     143 ( 0.0%) NilClass#to_i
     140 ( 0.0%) Paginate#render_to_output_buffer

mail

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/mail/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
Command: bundle check 2> /dev/null || bundle install
The Gemfile's dependencies are satisfied
Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
itr #1: 2852ms
Top 9 block calls by C methods (100.0% of all 49451 calls):
   42500 (85.9%) Array#select
    4150 ( 8.4%) Array#each
     800 ( 1.6%) Hash#each
     750 ( 1.5%) Array#map
     450 ( 0.9%) Array#reject
     450 ( 0.9%) Hash#each_pair
     300 ( 0.6%) Array#map!
      50 ( 0.1%) Integer#times
       1 ( 0.0%) Thread::Mutex#synchronize

Top 100 C method calls (98.6% of all 3330154 calls):
  676537 (20.3%) Array#[]
  405610 (12.2%) Integer#<=
  287826 ( 8.6%) Integer#==
  249879 ( 7.5%) Integer#+
  161384 ( 4.8%) BasicObject#!=
  151200 ( 4.5%) #<Class:Mail::Parsers::ReceivedParser>#_trans_keys
   98650 ( 3.0%) String#to_s
   86493 ( 2.6%) Integer#>
   85142 ( 2.6%) Integer#-
   79892 ( 2.4%) String#[]
   79892 ( 2.4%) Integer#<<
   79892 ( 2.4%) String#ord
   76700 ( 2.3%) #<Class:Mail::Parsers::ReceivedParser>#_trans_actions
   50400 ( 1.5%) #<Class:Mail::Parsers::ReceivedParser>#_indicies
   50400 ( 1.5%) #<Class:Mail::Parsers::ReceivedParser>#_trans_targs
   50400 ( 1.5%) #<Class:Mail::Parsers::ReceivedParser>#_index_offsets
   50400 ( 1.5%) #<Class:Mail::Parsers::ReceivedParser>#_key_spans
   42500 ( 1.3%) String#casecmp
   27726 ( 0.8%) #<Class:Mail::Parsers::MessageIdsParser>#_trans_keys
   23900 ( 0.7%) Kernel#kind_of?
   23250 ( 0.7%) #<Class:Mail::Parsers::AddressListsParser>#_trans_keys
   20850 ( 0.6%) #<Class:Mail::Parsers::ContentTypeParser>#_trans_keys
   16600 ( 0.5%) BasicObject#!
   14600 ( 0.4%) Regexp#===
   11350 ( 0.3%) String#downcase
   10601 ( 0.3%) Kernel#respond_to?
   10500 ( 0.3%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#_trans_keys
   10242 ( 0.3%) #<Class:Mail::Parsers::MessageIdsParser>#_trans_actions
   10150 ( 0.3%) String#=~
    9650 ( 0.3%) Array#empty?
    9242 ( 0.3%) #<Class:Mail::Parsers::MessageIdsParser>#_key_spans
    9242 ( 0.3%) #<Class:Mail::Parsers::MessageIdsParser>#_trans_targs
    9242 ( 0.3%) #<Class:Mail::Parsers::MessageIdsParser>#_indicies
    9242 ( 0.3%) #<Class:Mail::Parsers::MessageIdsParser>#_index_offsets
    9200 ( 0.3%) #<Class:Mail::Parsers::AddressListsParser>#_trans_actions
    8100 ( 0.2%) #<Class:Mail::Parsers::ContentTypeParser>#_trans_actions
    7750 ( 0.2%) #<Class:Mail::Parsers::AddressListsParser>#_key_spans
    7750 ( 0.2%) #<Class:Mail::Parsers::AddressListsParser>#_index_offsets
    7750 ( 0.2%) #<Class:Mail::Parsers::AddressListsParser>#_trans_targs
    7750 ( 0.2%) #<Class:Mail::Parsers::AddressListsParser>#_indicies
    7650 ( 0.2%) String#force_encoding
    7401 ( 0.2%) Kernel#is_a?
    7250 ( 0.2%) Array#first
    6950 ( 0.2%) #<Class:Mail::Parsers::ContentTypeParser>#_indicies
    6950 ( 0.2%) #<Class:Mail::Parsers::ContentTypeParser>#_key_spans
    6950 ( 0.2%) #<Class:Mail::Parsers::ContentTypeParser>#_index_offsets
    6950 ( 0.2%) #<Class:Mail::Parsers::ContentTypeParser>#_trans_targs
    6700 ( 0.2%) Integer#<
    6602 ( 0.2%) Class#new
    6350 ( 0.2%) Kernel#dup
    6350 ( 0.2%) Kernel#initialize_dup
    6200 ( 0.2%) String#initialize_copy
    6100 ( 0.2%) Hash#[]
    6100 ( 0.2%) Array#select
    6050 ( 0.2%) String#tr
    6050 ( 0.2%) Kernel#!~
    5850 ( 0.2%) Comparable#<
    5700 ( 0.2%) #<Class:Mail::Parsers::ContentDispositionParser>#_trans_keys
    5050 ( 0.2%) Regexp#to_s
    4950 ( 0.1%) String#<<
    4850 ( 0.1%) String#length
    4750 ( 0.1%) String#gsub!
    4600 ( 0.1%) Integer#div
    4500 ( 0.1%) Symbol#to_s
    4450 ( 0.1%) Array#length
    4300 ( 0.1%) String#downcase!
    4250 ( 0.1%) String#gsub
    4200 ( 0.1%) Mail::UnstructuredField#charset
    4200 ( 0.1%) Regexp#match
    4000 ( 0.1%) #<Class:Encoding>#find
    3900 ( 0.1%) Integer#<=>
    3850 ( 0.1%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#_trans_actions
    3500 ( 0.1%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#_trans_targs
    3500 ( 0.1%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#_index_offsets
    3500 ( 0.1%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#_key_spans
    3500 ( 0.1%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#_indicies
    3250 ( 0.1%) String#slice
    3100 ( 0.1%) String#encoding
    2800 ( 0.1%) String#strip
    2800 ( 0.1%) String#index
    2750 ( 0.1%) Kernel#nil?
    2500 ( 0.1%) BasicObject#==
    2300 ( 0.1%) #<Class:Mail::Parsers::ContentDispositionParser>#_trans_actions
    2150 ( 0.1%) Array#each
    2050 ( 0.1%) String#empty?
    2000 ( 0.1%) Array#shift
    2000 ( 0.1%) Encoding#to_s
    2000 ( 0.1%) #<Class:Mail::Ruby19>#charset_encoder
    2000 ( 0.1%) String#<=>
    2000 ( 0.1%) String#encode
    1900 ( 0.1%) String#split
    1900 ( 0.1%) #<Class:Mail::Parsers::ContentDispositionParser>#_trans_targs
    1900 ( 0.1%) #<Class:Mail::Parsers::ContentDispositionParser>#_index_offsets
    1900 ( 0.1%) #<Class:Mail::Parsers::ContentDispositionParser>#_indicies
    1900 ( 0.1%) #<Class:Mail::Parsers::ContentDispositionParser>#_key_spans
    1800 ( 0.1%) Struct#initialize
    1750 ( 0.1%) String#ascii_only?
    1750 ( 0.1%) String#rstrip
    1700 ( 0.1%) Array#include?
    1650 ( 0.0%) String#==

Top 100 Ruby method calls (89.1% of all 259958 calls):
   46150 (17.8%) Mail::Field#name
   42500 (16.3%) Mail::Field#responsible_for?
   11900 ( 4.6%) #<Class:Mail::Utilities>#blank?
    7700 ( 3.0%) Mail::Field#field_order_id
    6050 ( 2.3%) Mail::Header#fields
    5450 ( 2.1%) Mail::Header#select_field_for
    5100 ( 2.0%) Mail::Message#header
    5050 ( 1.9%) Mail::Field#field
    4900 ( 1.9%) Mail::Utilities#dasherize
    4900 ( 1.9%) Mail::Field#method_missing
    4300 ( 1.7%) Mail::Header#[]
    3850 ( 1.5%) Mail::Field#<=>
    3250 ( 1.3%) Mail::ParserTools#chars
    2950 ( 1.1%) Mail::StructuredField#charset=
    2900 ( 1.1%) Mail::CommonField#value
    2350 ( 0.9%) Mail::ContentTypeField#main_type
    2000 ( 0.8%) #<Class:Mail::Ruby19>#convert_to_encoding
    2000 ( 0.8%) Mail::Ruby19::BestEffortCharsetEncoder#pick_encoding
    2000 ( 0.8%) #<Class:Mail::Ruby19>#transcode_charset
    2000 ( 0.8%) Mail::Ruby19::BestEffortCharsetEncoder#encode
    2000 ( 0.8%) #<Class:Mail::Encodings>#transcode_charset
    2000 ( 0.8%) Mail::UnstructuredField#encode_crlf
    2000 ( 0.8%) #<Class:Mail::Ruby19>#pick_encoding
    1850 ( 0.7%) Mail::CommonField#value=
    1700 ( 0.7%) Mail::CommonField#name=
    1650 ( 0.6%) Mail::Field#create_field
    1650 ( 0.6%) Mail::Field#field_class_for
    1650 ( 0.6%) Mail::Field#new_field
    1600 ( 0.6%) Mail::Message#body
    1550 ( 0.6%) Mail::Header#limited_field?
    1550 ( 0.6%) Mail::Field#unfold
    1500 ( 0.6%) Mail::StructuredField#initialize
    1450 ( 0.6%) Mail::FieldList#<<
    1450 ( 0.6%) Mail::Header#charset
    1450 ( 0.6%) Mail::Field#initialize
    1450 ( 0.6%) Mail::Message#has_content_type?
    1350 ( 0.5%) Mail::ContentDispositionField#element
    1350 ( 0.5%) #<Class:Mail::Field>#parse
    1350 ( 0.5%) #<Class:Mail::Field>#split
    1350 ( 0.5%) Kernel#class
    1350 ( 0.5%) #<Class:0x0000000106419e28>#__getobj__
    1250 ( 0.5%) #<Class:Mail::Encodings>#decode_encode
    1150 ( 0.4%) Mail::Utilities#underscoreize
    1100 ( 0.4%) Mail::IndifferentHash#update
     950 ( 0.4%) Mail::Body#parts
     950 ( 0.4%) #<Class:Mail::Encodings>#get_name
     950 ( 0.4%) #<Class:Mail::Encodings>#get_encoding
     850 ( 0.3%) Mail::ContentTypeField#parameters
     800 ( 0.3%) Mail::Address#get_comments
     800 ( 0.3%) Mail::Address#comments
     700 ( 0.3%) Mail::Address#get_local
     700 ( 0.3%) Mail::ReceivedField#date_time
     700 ( 0.3%) Mail::Address#get_domain
     700 ( 0.3%) Mail::ReceivedField#element
     650 ( 0.3%) Mail::IndifferentHash#initialize
     650 ( 0.3%) #<Class:0x0000000106419e28>#empty?
     650 ( 0.3%) Mail::Body#multipart?
     600 ( 0.2%) Mail::Body#raw_source
     600 ( 0.2%) Mail::ContentTypeField#element
     600 ( 0.2%) Mail::CommonMessageId#element
     600 ( 0.2%) Mail::ParameterHash#[]
     550 ( 0.2%) #<Class:Mail::Encodings::TransferEncoding>#to_s
     500 ( 0.2%) Mail::CommonAddress#address_list
     500 ( 0.2%) Mail::ContentTypeField#string
     500 ( 0.2%) Mail::ContentTypeField#sub_type
     500 ( 0.2%) Mail::ContentDispositionField#parameters
     500 ( 0.2%) Mail::Address#strip_all_comments
     450 ( 0.2%) Mail::Message#default
     450 ( 0.2%) Mail::IndifferentHash#convert_key
     450 ( 0.2%) #<Class:0x0000000106419e28>#each
     450 ( 0.2%) Mail::IndifferentHash#convert_value
     400 ( 0.2%) Mail::ContentTransferEncodingField#element
     400 ( 0.2%) Mail::Message#has_content_transfer_encoding?
     400 ( 0.2%) Mail::Message#main_type
     400 ( 0.2%) Mail::ContentTransferEncodingField#encoding
     400 ( 0.2%) Mail::Body#encoding
     400 ( 0.2%) Mail::CommonField#name
     350 ( 0.1%) Mail::Address#local
     350 ( 0.1%) Mail::ContentDispositionField#disposition_type
     350 ( 0.1%) Mail::StructuredField#default
     350 ( 0.1%) Mail::ReceivedElement#initialize
     350 ( 0.1%) Mail::ReceivedField#initialize
     350 ( 0.1%) Mail::ReceivedField#parse
     350 ( 0.1%) #<Class:Mail::Utilities>#binary_unsafe_to_crlf
     350 ( 0.1%) Mail::StructuredField#errors
     350 ( 0.1%) #<Class:Mail::Parsers::ReceivedParser>#parse
     350 ( 0.1%) Mail::Address#address
     350 ( 0.1%) Mail::Address#domain
     350 ( 0.1%) #<Class:Mail::Parsers::ContentTransferEncodingParser>#parse
     350 ( 0.1%) Mail::ContentTransferEncodingElement#initialize
     350 ( 0.1%) Mail::ContentTransferEncodingField#parse
     350 ( 0.1%) #<Class:Mail::Encodings>#value_decode
     350 ( 0.1%) Mail::ContentTransferEncodingField#initialize
     350 ( 0.1%) Mail::ReceivedField#encoded
     350 ( 0.1%) Mail::ReceivedField#info
     350 ( 0.1%) Mail::ReceivedField#formatted_date
     300 ( 0.1%) #<Class:Mail::Utilities>#safe_for_line_ending_conversion?
     300 ( 0.1%) Mail::Address#encoded
     300 ( 0.1%) Mail::AddressList#addresses_grouped_by_group
     300 ( 0.1%) Mail::CommonAddress#groups

psych-load

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/psych-load/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
Command: bundle check 2> /dev/null || bundle install
The Gemfile's dependencies are satisfied
Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
itr #1: 33062ms
Top 3 block calls by C methods (100.0% of all 535404 calls):
  535300 (100.0%) Array#each
     100 ( 0.0%) Integer#times
       4 ( 0.0%) Hash#[]

Top 66 C method calls (100.0% of all 23760136 calls):
 2067900 ( 8.7%) Hash#[]
 1942700 ( 8.2%) BasicObject#!
 1500800 ( 6.3%) Psych::Nodes::Scalar#tag
 1124600 ( 4.7%) Psych::Nodes::Node#children
 1035901 ( 4.4%) Class#new
 1034100 ( 4.4%) Hash#empty?
 1034100 ( 4.4%) Psych::Nodes::Node#start_line=
 1034100 ( 4.4%) Psych::Nodes::Node#start_column=
 1033801 ( 4.4%) Array#<<
 1033800 ( 4.4%) Psych::Nodes::Node#end_column=
 1033800 ( 4.4%) Psych::Nodes::Node#end_line=
  952600 ( 4.0%) String#match?
  945700 ( 4.0%) Psych::Visitors::ToRuby#class_loader
  943300 ( 4.0%) Psych::Nodes::Scalar#quoted
  943300 ( 4.0%) Psych::Nodes::Scalar#anchor
  943300 ( 4.0%) Psych::Nodes::Scalar#value
  579000 ( 2.4%) String#==
  557500 ( 2.3%) String#empty?
  557300 ( 2.3%) Hash#key?
  556601 ( 2.3%) Integer#>
  556600 ( 2.3%) String#length
  498504 ( 2.1%) Hash#[]=
  498500 ( 2.1%) String#-@
  498500 ( 2.1%) Kernel#is_a?
  176200 ( 0.7%) Psych::Nodes::Mapping#tag
  127600 ( 0.5%) Array#push
   90800 ( 0.4%) Array#pop
   90800 ( 0.4%) Array#last
   90600 ( 0.4%) Array#each
   88101 ( 0.4%) Array#size
   88100 ( 0.4%) Psych::Nodes::Mapping#anchor
   88100 ( 0.4%) Enumerable#each_slice
    4800 ( 0.0%) Psych::Nodes::Sequence#tag
    2400 ( 0.0%) NilClass#===
    2400 ( 0.0%) Psych::Nodes::Sequence#anchor
     600 ( 0.0%) Array#map
     300 ( 0.0%) #<Class:0x0000000105716230>::Config#domain_types
     300 ( 0.0%) #<Class:0x0000000105716230>::Config#load_tags
     300 ( 0.0%) BasicObject#initialize
     300 ( 0.0%) Hash#initialize_copy
     300 ( 0.0%) Kernel#initialize_dup
     300 ( 0.0%) Kernel#dup
     300 ( 0.0%) Module#to_s
     300 ( 0.0%) Psych::Nodes::Document#implicit_end=
     300 ( 0.0%) Psych::Parser#parse
     300 ( 0.0%) Kernel#block_given?
     300 ( 0.0%) Array#first
       4 ( 0.0%) String#gsub
       4 ( 0.0%) Module#name
       3 ( 0.0%) Integer#+
       2 ( 0.0%) #<Class:Process>#clock_gettime
       1 ( 0.0%) Float#-
       1 ( 0.0%) Integer#*
       1 ( 0.0%) Hash#compare_by_identity
       1 ( 0.0%) Hash#initialize
       1 ( 0.0%) Float#to_i
       1 ( 0.0%) Kernel#puts
       1 ( 0.0%) IO#puts
       1 ( 0.0%) IO#write
       1 ( 0.0%) Integer#>=
       1 ( 0.0%) Array#join
       1 ( 0.0%) Float#>=
       1 ( 0.0%) Float#to_s
       1 ( 0.0%) #<Class:IO>#write
       1 ( 0.0%) Array#[]
       1 ( 0.0%) Integer#times

Top 60 Ruby method calls (100.0% of all 17795207 calls):
 1125200 ( 6.3%) Psych::TreeBuilder#event_location
 1034100 ( 5.8%) Psych::Visitors::ToRuby#accept
 1034100 ( 5.8%) Psych::TreeBuilder#set_start_location
 1034100 ( 5.8%) Psych::Visitors::Visitor#visit
 1034100 ( 5.8%) Kernel#class
 1034100 ( 5.8%) Psych::Visitors::Visitor#dispatch
 1034100 ( 5.8%) Psych::Visitors::Visitor#accept
 1033800 ( 5.8%) Psych::Visitors::ToRuby#register
 1033800 ( 5.8%) Psych::TreeBuilder#set_end_location
  945700 ( 5.3%) Psych::Visitors::ToRuby#resolve_class
  945700 ( 5.3%) Psych::ClassLoader#load
  943300 ( 5.3%) Psych::TreeBuilder#scalar
  943300 ( 5.3%) Psych::Visitors::ToRuby#deserialize
  943300 ( 5.3%) Psych::Visitors::ToRuby#visit_Psych_Nodes_Scalar
  943300 ( 5.3%) Psych::Nodes::Scalar#initialize
  943300 ( 5.3%) Psych::TreeBuilder#set_location
  557500 ( 3.1%) Psych::ScalarScanner#tokenize
  498500 ( 2.8%) Psych::Visitors::ToRuby#deduplicate
   91100 ( 0.5%) Psych::Nodes::Node#initialize
   91100 ( 0.5%) Psych::TreeBuilder#push
   90800 ( 0.5%) Psych::TreeBuilder#pop
   88100 ( 0.5%) Psych::Visitors::ToRuby#visit_Psych_Nodes_Mapping
   88100 ( 0.5%) Psych::TreeBuilder#end_mapping
   88100 ( 0.5%) Psych::TreeBuilder#start_mapping
   88100 ( 0.5%) Psych::Nodes::Mapping#initialize
   88100 ( 0.5%) Psych::Visitors::ToRuby#revive_hash
    2400 ( 0.0%) Psych::Visitors::ToRuby#visit_Psych_Nodes_Sequence
    2400 ( 0.0%) Psych::Nodes::Sequence#initialize
    2400 ( 0.0%) Psych::Visitors::ToRuby#register_empty
    2400 ( 0.0%) Psych::TreeBuilder#end_sequence
    2400 ( 0.0%) Psych::TreeBuilder#start_sequence
     900 ( 0.0%) Ractor#[]
     900 ( 0.0%) #<Class:Ractor>#current
     600 ( 0.0%) #<Class:Psych>#config
     300 ( 0.0%) Psych::TreeBuilder#start_stream
     300 ( 0.0%) Psych::Nodes::Stream#initialize
     300 ( 0.0%) Psych::Parser#initialize
     300 ( 0.0%) Psych::TreeBuilder#initialize
     300 ( 0.0%) Psych::Visitors::ToRuby#visit_Psych_Nodes_Document
     300 ( 0.0%) Psych::Nodes::Document#root
     300 ( 0.0%) Psych::Handlers::DocumentStream#initialize
     300 ( 0.0%) #<Class:Psych>#parse_stream
     300 ( 0.0%) #<Class:Psych>#parse
     300 ( 0.0%) #<Class:Psych>#safe_load
     300 ( 0.0%) #<Class:Psych>#load
     300 ( 0.0%) Psych::Nodes::Document#initialize
     300 ( 0.0%) Psych::ClassLoader::Restricted#initialize
     300 ( 0.0%) Psych::ClassLoader#initialize
     300 ( 0.0%) Psych::ScalarScanner#initialize
     300 ( 0.0%) Psych::Visitors::ToRuby#initialize
     300 ( 0.0%) #<Class:Psych>#load_tags
     300 ( 0.0%) #<Class:Psych>#domain_types
     300 ( 0.0%) Psych::Handlers::DocumentStream#start_document
     300 ( 0.0%) Psych::Handlers::DocumentStream#end_document
       2 ( 0.0%) TracePoint#disable
       1 ( 0.0%) Ractor#[]=
       1 ( 0.0%) #<Class:Psych::Visitors::Visitor>#dispatch_cache
       1 ( 0.0%) Object#run_benchmark
       1 ( 0.0%) #<Class:Benchmark>#realtime
       1 ( 0.0%) TracePoint#enable

railsbench

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/railsbench/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
Command: bundle check 2> /dev/null || bundle install
...
Bundle complete! 13 Gemfile dependencies, 63 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Command: bin/rails db:migrate db:seed
Using 100 posts in the database
itr #1: 14787ms
Top 41 block calls by C methods (100.0% of all 805035 calls):
  224448 (27.9%) Array#each
  155760 (19.3%) Hash#each_pair
   83229 (10.3%) Hash#each
   53766 ( 6.7%) ActiveSupport::OrderedOptions#[]
   39740 ( 4.9%) Hash#transform_keys!
   37946 ( 4.7%) Array#map
   32221 ( 4.0%) Monitor#synchronize
   29970 ( 3.7%) Array#reject!
   19301 ( 2.4%) Hash#each_key
   18348 ( 2.3%) Hash#delete_if
   17949 ( 2.2%) Hash#fetch
   13969 ( 1.7%) Array#any?
    9970 ( 1.2%) Array#select
    9075 ( 1.1%) Hash#[]
    7070 ( 0.9%) Integer#times
    6533 ( 0.8%) #<Class:Thread>#handle_interrupt
    6000 ( 0.7%) String#sub
    5983 ( 0.7%) Hash#each_value
    4026 ( 0.5%) Array#initialize
    4002 ( 0.5%) BasicObject#instance_exec
    4000 ( 0.5%) Array#all?
    3971 ( 0.5%) Array#map!
    3970 ( 0.5%) Array#zip
    2600 ( 0.3%) Array#reverse_each
    2600 ( 0.3%) Hash#keep_if
    2155 ( 0.3%) Thread::Mutex#synchronize
    2000 ( 0.2%) Hash#delete
    2000 ( 0.2%) Array#collect
    1983 ( 0.2%) Hash#transform_values
     325 ( 0.0%) Kernel#loop
      67 ( 0.0%) Enumerable#reverse_each
      19 ( 0.0%) String#scan
      15 ( 0.0%) Array#reject
       9 ( 0.0%) Kernel#catch
       4 ( 0.0%) Hash#transform_keys
       3 ( 0.0%) Module#class_eval
       3 ( 0.0%) Class#initialize
       2 ( 0.0%) String#gsub!
       1 ( 0.0%) String#sub!
       1 ( 0.0%) Module#initialize
       1 ( 0.0%) Hash#select

Top 100 C method calls (84.8% of all 9532341 calls):
 1105900 (11.6%) Hash#[]
  453811 ( 4.8%) Hash#[]=
  350840 ( 3.7%) Hash#fetch
  348210 ( 3.7%) Module#===
  344733 ( 3.6%) String#to_s
  305403 ( 3.2%) Class#new
  215855 ( 2.3%) BasicObject#!
  197383 ( 2.1%) Kernel#is_a?
  143338 ( 1.5%) Kernel#initialize_dup
  143332 ( 1.5%) Kernel#dup
  130418 ( 1.4%) Array#each
  128396 ( 1.3%) Kernel#nil?
  127168 ( 1.3%) String#getbyte
  127116 ( 1.3%) String#==
  118219 ( 1.2%) Array#[]
  116544 ( 1.2%) #<Class:Thread>#current
  114213 ( 1.2%) Kernel#respond_to?
  106518 ( 1.1%) Hash#key?
  105765 ( 1.1%) Integer#+
  101810 ( 1.1%) Integer#<
   98206 ( 1.0%) String#empty?
   94699 ( 1.0%) Kernel#block_given?
   93628 ( 1.0%) ActiveSupport::OrderedOptions#[]
   92093 ( 1.0%) Thread#[]
   90291 ( 0.9%) Array#empty?
   82735 ( 0.9%) BasicObject#==
   75565 ( 0.8%) String#gsub!
   74273 ( 0.8%) Symbol#to_s
   71723 ( 0.8%) String#initialize
   71216 ( 0.7%) Hash#initialize_copy
   70454 ( 0.7%) Array#hash
   70357 ( 0.7%) Hash#delete
   63584 ( 0.7%) Integer#^
   63584 ( 0.7%) String#setbyte
   62658 ( 0.7%) ActionController::Metal#_request
   60265 ( 0.6%) String#<<
   58030 ( 0.6%) ActiveModel::LazyAttributeHash#delegate_hash
   56920 ( 0.6%) Kernel#hash
   55511 ( 0.6%) Array#map
   48763 ( 0.5%) ActionView::Helpers::ControllerHelper#_controller
   47772 ( 0.5%) Array#include?
   46463 ( 0.5%) Hash#empty?
   45231 ( 0.5%) #<Class:Process>#clock_gettime
   44878 ( 0.5%) Array#eql?
   44639 ( 0.5%) Array#any?
   44591 ( 0.5%) Array#first
   44012 ( 0.5%) Kernel#kind_of?
   43701 ( 0.5%) Integer#==
   42172 ( 0.4%) CGI::Escape#escapeHTML
   41090 ( 0.4%) Hash#each
   40026 ( 0.4%) ActiveModel::Attribute#type
   39388 ( 0.4%) Kernel#public_send
   37966 ( 0.4%) ActiveModel::Attribute#value_before_type_cast
   37952 ( 0.4%) String#downcase
   37753 ( 0.4%) ActionDispatch::Cookies::CookieJar#request
   37438 ( 0.4%) String#initialize_copy
   36112 ( 0.4%) BasicObject#initialize
   35569 ( 0.4%) ActiveModel::AttributeSet#attributes
   35470 ( 0.4%) JSON::Ext::Generator::GeneratorMethods::String#to_json
   35470 ( 0.4%) #<Class:ActiveSupport::JSON::Encoding>#escape_html_entities_in_json
   35102 ( 0.4%) Regexp#match?
   33984 ( 0.4%) Array#initialize_copy
   33706 ( 0.4%) ActiveSupport::SafeBuffer#concat
   32961 ( 0.3%) Hash#merge
   32221 ( 0.3%) Monitor#synchronize
   31574 ( 0.3%) Module#==
   31162 ( 0.3%) String#scrub
   30257 ( 0.3%) Class#superclass
   29934 ( 0.3%) Array#unshift
   29922 ( 0.3%) Hash#initialize
   28130 ( 0.3%) String#freeze
   27997 ( 0.3%) Array#[]=
   27899 ( 0.3%) Array#pop
   27777 ( 0.3%) Kernel#freeze
   27691 ( 0.3%) #<Class:ActiveSupport::Notifications>#notifier
   27674 ( 0.3%) Array#last
   27010 ( 0.3%) Kernel#instance_variable_defined?
   26923 ( 0.3%) BasicObject#!=
   26732 ( 0.3%) Hash#each_pair
   26392 ( 0.3%) Array#join
   25341 ( 0.3%) String#concat
   25192 ( 0.3%) NilClass#nil?
   24637 ( 0.3%) String#split
   24546 ( 0.3%) NilClass#===
   24494 ( 0.3%) Hash#merge!
   23600 ( 0.2%) String#force_encoding
   22480 ( 0.2%) ActiveModel::LazyAttributeHash#types
   22480 ( 0.2%) ActiveModel::LazyAttributeHash#values
   22480 ( 0.2%) ActiveModel::LazyAttributeHash#additional_types
   22307 ( 0.2%) String#to_i
   22261 ( 0.2%) Array#size
   21987 ( 0.2%) Hash#to_hash
   21897 ( 0.2%) Hash#default
   20000 ( 0.2%) ActionDispatch::Response#header
   19910 ( 0.2%) Hash#default_proc
   19300 ( 0.2%) MatchData#[]
   19292 ( 0.2%) Regexp#match
   17970 ( 0.2%) ActionController::Metal#_response
   17949 ( 0.2%) ActiveSupport::ParameterFilter::CompiledFilter#deep_regexps
   17352 ( 0.2%) ActiveModel::Attribute#name

Top 100 Ruby method calls (49.5% of all 6470859 calls):
  254060 ( 3.9%) Rack::Request::Env#get_header
  137854 ( 2.1%) Concurrent::Map#[]
  137854 ( 2.1%) Concurrent::Collection::NonConcurrentMapBackend#[]
  132074 ( 2.0%) Kernel#class
  124000 ( 1.9%) ActionController::Renderer#rack_value_for
  124000 ( 1.9%) ActionController::Renderer#rack_key_for
   81807 ( 1.3%) Set#include?
   70778 ( 1.1%) ActiveSupport::SafeBuffer#html_safe?
   67144 ( 1.0%) ActiveSupport::PerThreadRegistry#instance
   62399 ( 1.0%) Symbol#to_sym
   55279 ( 0.9%) ActiveSupport::JSON::Encoding::JSONGemEncoder#jsonify
   42172 ( 0.7%) Object#html_safe?
   41948 ( 0.6%) Rack::Request::Env#set_header
   35876 ( 0.6%) ActiveSupport::HashWithIndifferentAccess#convert_key
   35752 ( 0.6%) ActiveModel::Attribute#value
   35556 ( 0.5%) ActiveModel::AttributeSet#[]
   35550 ( 0.5%) ActiveModel::AttributeSet#fetch_value
   35550 ( 0.5%) ActiveModel::LazyAttributeHash#[]
   35550 ( 0.5%) ActiveRecord::AttributeMethods::Read#_read_attribute
   35483 ( 0.5%) ActiveSupport::ToJsonWithActiveSupportEncoder#to_json
   35470 ( 0.5%) ActiveSupport::JSON::Encoding::JSONGemEncoder::EscapedString#to_json
   34636 ( 0.5%) Object#present?
   33883 ( 0.5%) Rack::Request::Env#fetch_header
   33779 ( 0.5%) ActionDispatch::Cookies::AbstractCookieJar#request
   33706 ( 0.5%) ActionView::OutputBuffer#safe_concat
   32189 ( 0.5%) MonitorMixin#mon_synchronize
   31162 ( 0.5%) #<Class:ERB::Util>#unwrapped_html_escape
   31162 ( 0.5%) ActiveSupport::Multibyte::Unicode#tidy_bytes
   28015 ( 0.4%) ActionView::OutputBuffer#<<
   27921 ( 0.4%) ActiveSupport::SubscriberQueueRegistry#get_queue
   27921 ( 0.4%) ActiveSupport::Subscriber#event_stack
   27798 ( 0.4%) ActiveSupport::Notifications::Fanout#listeners_for
   25940 ( 0.4%) #<Class:0x0000000103330fa0>#logger
   24464 ( 0.4%) ActiveModel::Attribute#initialize
   24279 ( 0.4%) ActiveSupport::SafeBuffer#initialize
   24041 ( 0.4%) ActiveSupport::SafeBuffer#concat
   24041 ( 0.4%) ActiveSupport::SafeBuffer#html_escape_interpolated_argument
   23987 ( 0.4%) Rack::Utils::HeaderHash#[]=
   23942 ( 0.4%) ActiveSupport::Configurable::ClassMethods#config
   23922 ( 0.4%) Rack::Request::Helpers#allowed_scheme
   22486 ( 0.3%) #<Class:ActiveModel::Attribute>#from_database
   22480 ( 0.3%) ActiveModel::Attribute::FromDatabase#type_cast
   22480 ( 0.3%) ActiveModel::LazyAttributeHash#assign_default_value
   22105 ( 0.3%) ActionView::Helpers::TagHelper::TagBuilder#tag_option
   22000 ( 0.3%) #<Class:0x0000000106ac60f0>#__getobj__
   22000 ( 0.3%) ActionDispatch::Request#initialize
   22000 ( 0.3%) Rack::Request::Env#initialize
   22000 ( 0.3%) ActionDispatch::Http::URL#initialize
   22000 ( 0.3%) ActionDispatch::Http::FilterParameters#initialize
   21940 ( 0.3%) #<Class:ActionController::Base>#logger
   21940 ( 0.3%) ActionController::LogSubscriber#logger
   21856 ( 0.3%) ActiveRecord::ConnectionHandling#connection_specification_name
   21022 ( 0.3%) ActiveSupport::JSON::Encoding::JSONGemEncoder::EscapedString#to_s
   20714 ( 0.3%) ActionDispatch::Journey::Format#evaluate
   20357 ( 0.3%) Rack::Request::Helpers#script_name
   20000 ( 0.3%) Rack::Request::Helpers#path_info
   19922 ( 0.3%) ActiveSupport::Configurable#config
   19896 ( 0.3%) ActionDispatch::Request::Session#loaded?
   19846 ( 0.3%) ActiveSupport::HashWithIndifferentAccess#convert_value
   19414 ( 0.3%) #<Module:0x00000001019a15f8>#_routes
   18615 ( 0.3%) #<Class:0x00000001036ba0b8>#get_time
   18615 ( 0.3%) #<Class:Concurrent>#monotonic_time
   18614 ( 0.3%) #<Class:GC>#stat
   18614 ( 0.3%) ActiveSupport::Notifications::Event#now_allocations
   18614 ( 0.3%) ActiveSupport::Notifications::Event#now_cpu
   18614 ( 0.3%) ActiveSupport::Notifications::Event#now
   18226 ( 0.3%) Jbuilder::Blank#==
   18226 ( 0.3%) Jbuilder#_blank?
   18040 ( 0.3%) ActiveRecord::AttributeMethods::PrimaryKey#id
   17957 ( 0.3%) Kernel#tap
   17610 ( 0.3%) ActiveModel::Type::Value#cast
   17510 ( 0.3%) ActiveModel::Type::Value#deserialize
   17200 ( 0.3%) #<Class:ActionView::Base>#logger
   17200 ( 0.3%) ActionView::LogSubscriber#logger
   17005 ( 0.3%) String#html_safe
   17005 ( 0.3%) ActiveSupport::SafeBuffer#to_s
   16359 ( 0.3%) ActiveSupport::NumericWithFormat#to_s
   15970 ( 0.2%) ActiveSupport::HashWithIndifferentAccess#update
   15940 ( 0.2%) ActionDispatch::Request#request_method
   15413 ( 0.2%) Object#presence
   15321 ( 0.2%) #<Class:ActionView::Template::Types>#type_klass
   14491 ( 0.2%) #<Class:ActiveSupport::Notifications>#instrument
   14491 ( 0.2%) ActiveSupport::Notifications::Fanout#listening?
   14000 ( 0.2%) #<Class:0x0000000106ac60f0>#[]
   14000 ( 0.2%) ActionDispatch::Response#get_header
   13970 ( 0.2%) ActionDispatch::Response#committed?
   13948 ( 0.2%) ActionDispatch::Request::Session::Options#[]
   13942 ( 0.2%) ActiveSupport::Callbacks::CallbackChain#empty?
   13942 ( 0.2%) ActiveSupport::Callbacks#run_callbacks
   13757 ( 0.2%) #<Module:0x0000000106ac5970>#_routes
   13365 ( 0.2%) ActionView::Resolver#cached
   13365 ( 0.2%) ActionView::Resolver::Cache#cache
   13365 ( 0.2%) ActionView::Resolver#find_all
   13320 ( 0.2%) String#blank?
   13313 ( 0.2%) Mime::Mimes#symbols
   13313 ( 0.2%) #<Class:ActionView::Template::Types>#symbols
   13307 ( 0.2%) ActiveSupport::Notifications::Instrumenter#start
   13307 ( 0.2%) ActiveSupport::Notifications::Fanout#start
   13270 ( 0.2%) Logger#info
   13270 ( 0.2%) ActiveSupport::LoggerThreadSafeLevel#add

ruby-lsp

$ WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0 ruby -Iharness-stats benchmarks/ruby-lsp/benchmark.rb
ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
Command: bundle check 2> /dev/null || bundle install
The Gemfile's dependencies are satisfied
itr #1: 4221ms
Top 56 block calls by C methods (100.0% of all 403539 calls):
  280215 (69.4%) Array#each
   47382 (11.7%) Array#select
   18163 ( 4.5%) Array#map
   11496 ( 2.8%) Array#any?
    8283 ( 2.1%) Array#rindex
    8233 ( 2.0%) Array#map!
    7376 ( 1.8%) Array#bsearch_index
    4737 ( 1.2%) Hash#each
    2907 ( 0.7%) Hash#[]
    2498 ( 0.6%) String#gsub
    2145 ( 0.5%) Array#delete_if
    1662 ( 0.4%) Hash#each_key
    1348 ( 0.3%) Hash#fetch
     915 ( 0.2%) BasicObject#instance_exec
     903 ( 0.2%) Array#reverse_each
     872 ( 0.2%) Hash#each_pair
     798 ( 0.2%) Array#each_index
     676 ( 0.2%) Array#reject!
     574 ( 0.1%) Array#reject
     320 ( 0.1%) Array#index
     281 ( 0.1%) Range#each
     259 ( 0.1%) String#each_line
     212 ( 0.1%) Array#all?
     198 ( 0.0%) #<Class:IO>#foreach
     194 ( 0.0%) Array#select!
     179 ( 0.0%) Module#module_eval
     128 ( 0.0%) Range#bsearch
      93 ( 0.0%) Module#module_exec
      80 ( 0.0%) Hash#each_value
      58 ( 0.0%) Array#drop_while
      58 ( 0.0%) Array#zip
      48 ( 0.0%) Module#class_eval
      35 ( 0.0%) Integer#upto
      29 ( 0.0%) Hash#select
      19 ( 0.0%) Class#initialize
      18 ( 0.0%) Array#count
      18 ( 0.0%) Enumerator::Yielder#<<
      18 ( 0.0%) Kernel#require
      15 ( 0.0%) Hash#merge!
      15 ( 0.0%) Integer#downto
      13 ( 0.0%) Array#to_h
      13 ( 0.0%) String#sub
      12 ( 0.0%) #<Class:Struct>#new
       7 ( 0.0%) Array#fetch
       6 ( 0.0%) Module#refine
       6 ( 0.0%) Hash#transform_values
       5 ( 0.0%) Kernel#catch
       4 ( 0.0%) Array#take_while
       4 ( 0.0%) #<Class:Dir>#chdir
       2 ( 0.0%) Kernel#loop
       2 ( 0.0%) Thread::Mutex#synchronize
       2 ( 0.0%) BasicObject#instance_eval
       2 ( 0.0%) Integer#times
       1 ( 0.0%) #<Class:IO>#open
       1 ( 0.0%) Kernel#require_relative
       1 ( 0.0%) Module#initialize

Top 100 C method calls (93.2% of all 3190698 calls):
  305572 ( 9.6%) Psych::Nodes::Scalar#value
  176300 ( 5.5%) String#==
  164582 ( 5.2%) RuboCop::AST::NodePattern::LexerRex#ss
  158085 ( 5.0%) Array#[]
  139667 ( 4.4%) Integer#+
  116768 ( 3.7%) Hash#[]
  104428 ( 3.3%) StringScanner#skip
   75888 ( 2.4%) Kernel#is_a?
   68923 ( 2.2%) String#empty?
   62047 ( 1.9%) Class#new
   60653 ( 1.9%) Symbol#==
   60348 ( 1.9%) Integer#<=
   54673 ( 1.7%) AST::Node#children
   53105 ( 1.7%) AST::Node#type
   53049 ( 1.7%) Array#<<
   49755 ( 1.6%) Integer#==
   45698 ( 1.4%) Symbol#match?
   45303 ( 1.4%) BasicObject#!
   32506 ( 1.0%) Array#size
   31201 ( 1.0%) RuboCop::AST::NodePattern::Compiler::Subcompiler#node
   31167 ( 1.0%) StringScanner#eos?
   30148 ( 0.9%) Psych::Nodes::Node#children
   29469 ( 0.9%) Array#[]=
   28255 ( 0.9%) String#to_i
   27414 ( 0.9%) Kernel#freeze
   25607 ( 0.8%) Array#hash
   25083 ( 0.8%) Integer#>
   25060 ( 0.8%) Integer#-
   23675 ( 0.7%) BasicObject#!=
   23372 ( 0.7%) Psych::Nodes::Node#start_column=
   23372 ( 0.7%) Psych::Nodes::Node#start_line=
   23344 ( 0.7%) Psych::Nodes::Node#end_column=
   23344 ( 0.7%) Psych::Nodes::Node#end_line=
   23195 ( 0.7%) Module#===
   22916 ( 0.7%) Integer#>=
   22843 ( 0.7%) Array#each
   22809 ( 0.7%) Range#begin
   22678 ( 0.7%) Kernel#block_given?
   22516 ( 0.7%) Array#empty?
   22065 ( 0.7%) Psych::Nodes::Scalar#tag
   20530 ( 0.6%) Kernel#nil?
   20157 ( 0.6%) Hash#fetch
   19822 ( 0.6%) Range#max
   19635 ( 0.6%) Hash#[]=
   19134 ( 0.6%) RuboCop::AST::NodePattern::LexerRex#state
   17175 ( 0.5%) Kernel#hash
   16995 ( 0.5%) Array#first
   16970 ( 0.5%) StringScanner#matched
   16168 ( 0.5%) Symbol#===
   15256 ( 0.5%) #<Class:RuboCop::AST::NodePattern::Compiler::Subcompiler>#registry
   15142 ( 0.5%) RuboCop::AST::Token#type
   14863 ( 0.5%) Hash#empty?
   14433 ( 0.5%) String#match?
   14398 ( 0.5%) Module#method_added
   14265 ( 0.4%) String#to_sym
   13658 ( 0.4%) Array#last
   13396 ( 0.4%) Array#map
   13369 ( 0.4%) RuboCop::AST::NodePattern::Compiler::Subcompiler#compiler
   12930 ( 0.4%) Psych::Visitors::ToRuby#class_loader
   12745 ( 0.4%) RuboCop::Cop::Badge#department
   12380 ( 0.4%) Integer#<
   12362 ( 0.4%) Psych::Nodes::Scalar#quoted
   12362 ( 0.4%) Psych::Nodes::Scalar#anchor
   12088 ( 0.4%) Kernel#respond_to?
   12033 ( 0.4%) StringScanner#[]
   11866 ( 0.4%) Hash#key?
   11321 ( 0.4%) Parser::AST::Node#location
   11216 ( 0.4%) Kernel#public_send
   10397 ( 0.3%) String#length
   10034 ( 0.3%) Array#to_a
    9589 ( 0.3%) Array#include?
    9238 ( 0.3%) AST::Node#hash
    9038 ( 0.3%) Integer#<<
    8711 ( 0.3%) Array#shift
    8508 ( 0.3%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#access
    8448 ( 0.3%) Array#push
    8427 ( 0.3%) BasicObject#equal?
    7387 ( 0.2%) Array#join
    7231 ( 0.2%) Integer#<=>
    6911 ( 0.2%) String#[]
    6420 ( 0.2%) Symbol#<=>
    6395 ( 0.2%) RuboCop::Cop::Badge#cop_name
    6291 ( 0.2%) String#-@
    6001 ( 0.2%) Integer#===
    5927 ( 0.2%) NilClass#nil?
    5709 ( 0.2%) Symbol#to_s
    5607 ( 0.2%) Module#const_added
    4948 ( 0.2%) Array#any?
    4855 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#seq_head
    4648 ( 0.1%) Parser::Source::Range#begin_pos
    4566 ( 0.1%) SyntaxTree::Op#value
    4377 ( 0.1%) Enumerable#find
    4337 ( 0.1%) BasicObject#==
    4313 ( 0.1%) Numeric#negative?
    4211 ( 0.1%) String#split
    3667 ( 0.1%) Parser::Source::Range#end_pos
    3448 ( 0.1%) Integer#/
    3448 ( 0.1%) Integer#%
    3387 ( 0.1%) Array#map!
    3269 ( 0.1%) Kernel#initialize_dup

Top 100 Ruby method calls (71.2% of all 1067627 calls):
   56798 ( 5.3%) Kernel#class
   26257 ( 2.5%) Psych::TreeBuilder#event_location
   23372 ( 2.2%) Psych::TreeBuilder#set_start_location
   23344 ( 2.2%) Psych::TreeBuilder#set_end_location
   20515 ( 1.9%) Psych::TreeBuilder#scalar
   20515 ( 1.9%) Psych::Nodes::Scalar#initialize
   20515 ( 1.9%) Psych::TreeBuilder#set_location
   15253 ( 1.4%) RuboCop::AST::NodePattern::Compiler::Subcompiler#do_compile
   15253 ( 1.4%) RuboCop::AST::NodePattern::Compiler::Subcompiler#compile
   14134 ( 1.3%) Psych::Visitors::Visitor#visit
   14134 ( 1.3%) Psych::Visitors::Visitor#dispatch
   14134 ( 1.3%) Psych::Visitors::ToRuby#accept
   14134 ( 1.3%) Psych::Visitors::Visitor#accept
   14110 ( 1.3%) Psych::Visitors::ToRuby#register
   12946 ( 1.2%) Psych::ClassLoader#load
   12925 ( 1.2%) Psych::Visitors::ToRuby#resolve_class
   12651 ( 1.2%) RuboCop::AST::NodePattern::Parser#next_token
   12651 ( 1.2%) RuboCop::AST::NodePattern::LexerRex#next_token
   12582 ( 1.2%) RuboCop::AST::NodePattern::LexerRex#action
   12362 ( 1.2%) Psych::Visitors::ToRuby#deserialize
   12362 ( 1.2%) Psych::Visitors::ToRuby#visit_Psych_Nodes_Scalar
   12025 ( 1.1%) RuboCop::AST::NodePattern::Lexer#token
   12025 ( 1.1%) RuboCop::AST::NodePattern::Lexer#emit
   11100 ( 1.0%) RuboCop::Cop::Commissioner#with_cop_error_handling
   10867 ( 1.0%) Symbol#to_sym
   10012 ( 0.9%) #<Class:RuboCop::Cop::Base>#badge
    9913 ( 0.9%) AST::Node#initialize
    9913 ( 0.9%) Parser::AST::Node#assign_properties
    9693 ( 0.9%) Psych::ScalarScanner#tokenize
    9661 ( 0.9%) RuboCop::AST::Node#node_parts
    9288 ( 0.9%) RuboCop::AST::NodePattern::Builder#n
    9189 ( 0.9%) Parser::Source::Buffer#line_index_for_position
    8827 ( 0.8%) RuboCop::AST::NodePattern::Compiler::Subcompiler#initialize
    7990 ( 0.7%) Parser::Source::Buffer#line_for_position
    7834 ( 0.7%) RuboCop::AST::NodePattern::Node#arity_range
    7608 ( 0.7%) RuboCop::AST::NodePattern::Node#arity
    7432 ( 0.7%) Parser::Source::Range#line
    7269 ( 0.7%) RuboCop::AST::Descendence#each_child_node
    6998 ( 0.7%) Set#include?
    6948 ( 0.7%) RuboCop::AST::Node#send_type?
    6933 ( 0.6%) RuboCop::Cop::Base#cop_config
    6485 ( 0.6%) RuboCop::AST::Node#parent
    6298 ( 0.6%) Psych::Visitors::ToRuby#deduplicate
    6253 ( 0.6%) RuboCop::AST::NodePattern::Compiler#compile_as_node_pattern
    6253 ( 0.6%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#initialize
    6205 ( 0.6%) RuboCop::AST::NodePattern::Node#child
    6003 ( 0.6%) RuboCop::AST::MethodDispatchNode#method_name
    5977 ( 0.6%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#use_index_from_end
    5974 ( 0.6%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#handle_prev
    5635 ( 0.5%) RuboCop::Cop::Badge#hash
    5518 ( 0.5%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#visit_other_type
    5518 ( 0.5%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#compile_and_advance
    5032 ( 0.5%) #<Class:RuboCop::YAMLDuplicationChecker>#traverse
    4788 ( 0.4%) RuboCop::AST::Token#rescue_modifier?
    4090 ( 0.4%) #<Class:RuboCop::Cop::Base>#department
    4049 ( 0.4%) RuboCop::AST::Node#block_type?
    3986 ( 0.4%) RuboCop::AST::NodePattern::Parser#_reduce_43
    3894 ( 0.4%) RuboCop::Cop::Badge#to_s
    3583 ( 0.3%) Integer#-@
    3528 ( 0.3%) Set#add
    3412 ( 0.3%) #<Class:RuboCop::Cop::Base>#cop_name
    3320 ( 0.3%) RuboCop::AST::NodePattern::Compiler#with_temp_variables
    3259 ( 0.3%) RuboCop::AST::Token#line
    2917 ( 0.3%) RuboCop::AST::NodePattern::Parser#emit_call
    2917 ( 0.3%) RuboCop::AST::NodePattern::Builder#emit_call
    2899 ( 0.3%) RuboCop::AST::SendNode#first_argument_index
    2892 ( 0.3%) RuboCop::Config#for_cop
    2888 ( 0.3%) RuboCop::AST::Descendence#visit_descendants
    2885 ( 0.3%) Psych::Nodes::Node#initialize
    2885 ( 0.3%) Psych::TreeBuilder#push
    2857 ( 0.3%) Psych::TreeBuilder#pop
    2820 ( 0.3%) RuboCop::AST::NodePattern::Parser#emit_atom
    2820 ( 0.3%) RuboCop::AST::NodePattern::Builder#emit_atom
    2741 ( 0.3%) Parser::Source::Buffer#slice
    2693 ( 0.3%) RuboCop::AST::NodePattern::Builder#emit_list
    2687 ( 0.3%) RuboCop::Config#[]
    2646 ( 0.2%) RuboCop::AST::NodePattern#captures
    2498 ( 0.2%) #<Class:RuboCop::Cop::Badge>#camel_case
    2428 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#access_node
    2427 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#access_element
    2409 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#multiple_access
    2390 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#compile_guard_clause
    2367 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#visit_node_type
    2367 ( 0.2%) RuboCop::AST::NodePattern::Parser#_reduce_11
    2270 ( 0.2%) RuboCop::AST::Node#numblock_type?
    2202 ( 0.2%) RuboCop::AST::MethodDispatchNode#receiver
    2187 ( 0.2%) Parser::Source::Range#initialize
    2098 ( 0.2%) Parser::Source::Buffer#line_begins
    2068 ( 0.2%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#compile_remaining
    2065 ( 0.2%) RuboCop::Cop::Base#cop_name
    2017 ( 0.2%) RuboCop::AST::NodePattern::Parser#emit_list
    2008 ( 0.2%) Kernel#frozen?
    2007 ( 0.2%) RuboCop::AST::NodePattern::Node#in_sequence_head
    1958 ( 0.2%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#compile_terms
    1958 ( 0.2%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#compile_child_nb_guard
    1958 ( 0.2%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#remaining_arities
    1948 ( 0.2%) RuboCop::AST::NodePattern::Compiler::NodePatternSubcompiler#visit_sequence
    1948 ( 0.2%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#compile_sequence
    1948 ( 0.2%) RuboCop::AST::NodePattern::Compiler#compile_sequence
    1948 ( 0.2%) RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler#initialize

@k0kubun k0kubun requested a review from a team January 6, 2023 22:37
@maximecb
Copy link
Contributor

maximecb commented Jan 9, 2023

I like it and I think this is very useful 👍 One thing that I find a bit confusing though:

Top 10 block calls by C methods (100.0% of all 52000 calls):
   22000 (42.3%) Array#each
   10000 (19.2%) Hash#each_key
    6000 (11.5%) Array#map
   ...
Top 100 C method calls (93.0% of all 856021 calls):
   87000 (10.2%) Hash#[]

Here I'm not sure what the block calls count mean. Based on the name it sounds like the number of times a block has been called. However, the numbers seem much too low. That is, it seems improbable that a block inside Array#each has only been called 22K times when Hash#[] has been called 87K times.

So I'm assuming that Array#each is not counting calls to blocks (and so the number of loop iterations performed by Array#each), but rather counting the number of times that we call into Array#each as a whole, which is not as useful of a statistic. It would be more useful if we count count the number of loop iterations for each of these... Or maybe count both the number of calls to Array#each and also the total number of iterations (calls to a block) done by Array#each, and also display the average iteration count per Array#each call (which I assume is probably ~5 to 20 or something).

@k0kubun
Copy link
Member Author

k0kubun commented Jan 9, 2023

That is, it seems improbable that a block inside Array#each has only been called 22K times when Hash#[] has been called 87K times.

The numbers seem to come from activerecord benchmark. I wouldn't be too surprised even if an ActiveRecord benchmark turned out to be actually calling Hash#[] 4x more often than Array#each blocks. It'd be interesting to investigate why we end up with these numbers for understanding our workloads and double-checking that the trace implementation is working.

So I'm assuming that Array#each is not counting calls to blocks

If you have this code:

total = 0
run_benchmark do
  [1, 2, 3, 4, 5].each do |i|
    total += i
  end
end
puts "total: #{total}"

you get:

$ ruby trace.rb
Top 1 block calls by C methods (100.0% of all 5 calls):
       5 (100.0%) Array#each

Top 2 C method calls (100.0% of all 6 calls):
       5 (83.3%) Integer#+
       1 (16.7%) Array#each

Top 2 Ruby method calls (100.0% of all 3 calls):
       2 (66.7%) TracePoint#disable
       1 (33.3%) TracePoint#enable
total: 15

and I think it's working as I intended; it's counting the call of Array#each itself under "C method calls" and counting the call of blocks under "block calls by C methods".

Full script used for testing
def run_benchmark
  frames = []
  c_calls = Hash.new { 0 }
  c_loops = Hash.new { 0 }
  rb_calls = Hash.new { 0 }

  method_trace = TracePoint.new(:call, :c_call, :return, :c_return) do |tp|
    # Keep track of call frames to get the caller of :b_call
    case tp.event
    when :call, :c_call
      method_name = "#{tp.defined_class}##{tp.method_id}"
      frames.push([tp.event, method_name])
    when :return, :c_return
      frames.pop
    end

    # Count method calls
    case tp.event
    when :c_call
      c_calls[method_name] += 1
    when :call
      rb_calls[method_name] += 1
    end
  end

  block_trace = TracePoint.new(:b_call) do |tp|
    caller_event, caller_method = frames.last

    # Count block calls only when the caller is a C method
    if caller_event == :c_call
      c_loops[caller_method] += 1
    end
  end

  method_trace.enable
  block_trace.enable
  yield
ensure
  block_trace.disable
  method_trace.disable

  c_loops_total = c_loops.sum(&:last)
  c_loops = c_loops.sort_by { |_method, count| -count }.first(100)
  c_loops_ratio = 100.0 * c_loops.sum(&:last) / c_loops_total
  puts "Top #{c_loops.size} block calls by C methods (#{'%.1f' % c_loops_ratio}% of all #{c_loops_total} calls):"
  c_loops.each do |method, count|
    puts '%8d (%4.1f%%) %s' % [count, 100.0 * count / c_loops_total, method]
  end
  puts

  c_calls_total = c_calls.sum(&:last)
  c_calls = c_calls.sort_by { |_method, count| -count }.first(100)
  c_calls_ratio = 100.0 * c_calls.sum(&:last) / c_calls_total
  puts "Top #{c_calls.size} C method calls (#{'%.1f' % c_calls_ratio}% of all #{c_calls_total} calls):"
  c_calls.sort_by(&:last).reverse.first(100).each do |method, count|
    puts '%8d (%4.1f%%) %s' % [count, 100.0 * count / c_calls_total, method]
  end
  puts

  rb_calls_total = rb_calls.sum(&:last)
  rb_calls = rb_calls.sort_by { |_method, count| -count }.first(100)
  rb_calls_ratio = 100.0 * rb_calls.sum(&:last) / rb_calls_total
  puts "Top #{rb_calls.size} Ruby method calls (#{'%.1f' % rb_calls_ratio}% of all #{rb_calls_total} calls):"
  rb_calls.sort_by(&:last).reverse.first(100).each do |method, count|
    puts '%8d (%4.1f%%) %s' % [count, 100.0 * count / rb_calls_total, method]
  end
end

total = 0
run_benchmark do
  [1, 2, 3, 4, 5].each do |i|
    total += i
  end
end
puts "total: #{total}"

@maximecb
Copy link
Contributor

maximecb commented Jan 9, 2023

Then my intuition is wrong and there are way more C calls and Ruby calls than block calls.

I will merge this, but I think it could also be useful to add a breakdown of C calls, Ruby calls and block calls with the percentage for each, just to guide our optimization efforts. At the moment it seems like we might be spending a lot less time doing loop iterations than we thought?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants