├── .byebug_history ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── benchmark_driver-output-rubybench ├── .gitignore ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── benchmark_driver-output-rubybench.gemspec └── lib │ └── benchmark_driver │ ├── output │ ├── rubybench.rb │ └── rubybench │ │ └── version.rb │ └── runner │ ├── rsskb.rb │ └── seconds.rb ├── bundler └── benchmarks │ ├── bm_bundle_exec_binary.rb │ ├── bm_bundle_exec_gem.rb │ ├── bm_bundle_exec_shell.rb │ ├── bm_bundle_install_rails.rb │ ├── bm_bundle_install_rails_fixed.rb │ ├── bm_bundle_lock_gem.rb │ ├── bm_bundle_outdated_rails.rb │ ├── bm_parse_lockfile.rb │ ├── bm_resolve_cocoapods.rb │ ├── bm_resolve_gx_api_rails.rb │ ├── bm_resolve_rails.rb │ ├── driver.rb │ ├── gems │ └── noop-gem │ │ ├── bin │ │ └── noop-gem │ │ ├── lib │ │ └── noop │ │ │ ├── gem.rb │ │ │ └── gem │ │ │ └── version.rb │ │ └── noop-gem.gemspec │ ├── resolve_issue3687.rb │ └── support │ └── benchmark_bundler.rb ├── discourse ├── benchmarks │ ├── bench.rb │ └── patches │ │ └── active_support_duration.rb └── rails_ruby_bench │ ├── bench.rb │ └── patches │ └── assets_jq.rb ├── guides └── running_and_writing_rails_benchmarks.md ├── liquid_benchmarks ├── benchmark_liquid.rb ├── bm_parse.rb ├── bm_parse_and_render.rb ├── bm_render.rb └── driver.rb ├── optcarrot_benchmarks └── driver.rb ├── pg ├── Gemfile └── benchmarks │ ├── bm_discourse.rb │ ├── bm_scope_all.rb │ ├── bm_scope_all_over_select.rb │ ├── driver.rb │ ├── pg_suite_runner.rb │ └── support │ └── benchmark_pg.rb ├── rails ├── .bundle │ └── config ├── Gemfile └── benchmarks │ ├── actionpack_router.rb │ ├── actionpack_url_generation_others.rb │ ├── actionpack_url_generation_rest.rb │ ├── actionpack_url_generation_url_for.rb │ ├── actionview_partials.rb │ ├── activemodel_views.rb │ ├── assets │ └── javascripts │ │ ├── application.js │ │ ├── one.js.erb │ │ └── two.js │ ├── bm_actioncontroller_api.rb │ ├── bm_activerecord_create_string_columns.rb │ ├── bm_activerecord_destroy.rb │ ├── bm_activerecord_discourse.rb │ ├── bm_activerecord_finders_find_by_attributes.rb │ ├── bm_activerecord_finders_find_by_attributes_over_select.rb │ ├── bm_activerecord_finders_find_by_sql.rb │ ├── bm_activerecord_finders_first.rb │ ├── bm_activerecord_finders_first_over_select.rb │ ├── bm_activerecord_pluck.rb │ ├── bm_activerecord_pluck_with_scope.rb │ ├── bm_activerecord_preload.rb │ ├── bm_activerecord_save.rb │ ├── bm_activerecord_scope_all.rb │ ├── bm_activerecord_scope_all_over_select.rb │ ├── bm_activerecord_scope_all_with_default_scope.rb │ ├── bm_activerecord_scope_all_with_default_scope_over_select.rb │ ├── bm_activerecord_scope_where.rb │ ├── bm_activerecord_scope_where_over_select.rb │ ├── bm_activerecord_validations_invalid.rb │ ├── bm_activerecord_validations_valid.rb │ ├── bm_scaffold_create.rb │ ├── bm_scaffold_index.rb │ ├── bm_scaffold_new.rb │ ├── bm_scaffold_show.rb │ ├── bm_scaffold_update.rb │ ├── bm_sprockets_javascript.rb │ ├── driver.rb │ ├── form_partials │ ├── first.html.erb │ ├── heavy │ │ ├── _item.html.erb │ │ ├── _second.html.erb │ │ └── _third.html.erb │ └── layouts │ │ └── application.html.erb │ ├── partials │ ├── first.html.erb │ ├── heavy │ │ ├── _item.html.erb │ │ ├── _second.html.erb │ │ └── _third.html.erb │ └── layouts │ │ └── application.html.erb │ ├── support │ ├── benchmark_rails.rb │ ├── echo_channel.rb │ ├── request_helper.rb │ └── url_generation_base.rb │ └── views │ └── posts │ ├── _form.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── index.json.jbuilder │ ├── new.html.erb │ ├── show.html.erb │ └── show.json.jbuilder ├── ruby ├── benchmark │ ├── app_answer.rb │ ├── app_aobench.rb │ ├── app_erb.yml │ ├── app_factorial.rb │ ├── app_fib.rb │ ├── app_lc_fizzbuzz.rb │ ├── app_mandelbrot.rb │ ├── app_pentomino.rb │ ├── app_raise.rb │ ├── app_strconcat.rb │ ├── app_tak.rb │ ├── app_tarai.rb │ ├── app_uri.rb │ ├── array_sample_100k_10.rb │ ├── array_sample_100k_11.rb │ ├── array_sample_100k__100.rb │ ├── array_sample_100k__1k.rb │ ├── array_sample_100k__6k.rb │ ├── array_sample_100k___10k.rb │ ├── array_sample_100k___50k.rb │ ├── array_shift.rb │ ├── array_small_and.rb │ ├── array_small_diff.rb │ ├── array_small_or.rb │ ├── array_sort_block.rb │ ├── array_sort_float.rb │ ├── array_values_at_int.rb │ ├── array_values_at_range.rb │ ├── bighash.rb │ ├── cgi_escape_html.yml │ ├── complex_float_add.yml │ ├── complex_float_div.yml │ ├── complex_float_mul.yml │ ├── complex_float_new.yml │ ├── complex_float_power.yml │ ├── complex_float_sub.yml │ ├── dir_empty_p.rb │ ├── enum_lazy_grep_v_100.rb │ ├── enum_lazy_grep_v_20.rb │ ├── enum_lazy_grep_v_50.rb │ ├── enum_lazy_uniq_100.rb │ ├── enum_lazy_uniq_20.rb │ ├── enum_lazy_uniq_50.rb │ ├── erb_render.yml │ ├── fiber_chain.rb │ ├── fiber_chain.yml │ ├── file_chmod.rb │ ├── file_rename.rb │ ├── hash_aref_dsym.rb │ ├── hash_aref_dsym_long.rb │ ├── hash_aref_fix.rb │ ├── hash_aref_flo.rb │ ├── hash_aref_miss.rb │ ├── hash_aref_str.rb │ ├── hash_aref_sym.rb │ ├── hash_aref_sym_long.rb │ ├── hash_flatten.rb │ ├── hash_ident_flo.rb │ ├── hash_ident_num.rb │ ├── hash_ident_obj.rb │ ├── hash_ident_str.rb │ ├── hash_ident_sym.rb │ ├── hash_keys.rb │ ├── hash_literal_small2.rb │ ├── hash_literal_small4.rb │ ├── hash_literal_small8.rb │ ├── hash_long.rb │ ├── hash_shift.rb │ ├── hash_shift_u16.rb │ ├── hash_shift_u24.rb │ ├── hash_shift_u32.rb │ ├── hash_small2.rb │ ├── hash_small4.rb │ ├── hash_small8.rb │ ├── hash_to_proc.rb │ ├── hash_values.rb │ ├── int_quo.rb │ ├── io_copy_stream_write.rb │ ├── io_copy_stream_write_socket.rb │ ├── io_file_create.rb │ ├── io_file_read.rb │ ├── io_file_write.rb │ ├── io_nonblock_noex.rb │ ├── io_nonblock_noex2.rb │ ├── io_pipe_rw.rb │ ├── io_select.rb │ ├── io_select2.rb │ ├── io_select3.rb │ ├── irb_color.yml │ ├── irb_exec.yml │ ├── loop_for.rb │ ├── loop_generator.rb │ ├── loop_times.rb │ ├── loop_whileloop.rb │ ├── loop_whileloop2.rb │ ├── marshal_dump_flo.rb │ ├── marshal_dump_load_geniv.rb │ ├── marshal_dump_load_time.rb │ ├── match_gt4.rb │ ├── match_small.rb │ ├── range_last.yml │ ├── realpath.yml │ ├── require.yml │ ├── require_thread.yml │ ├── securerandom.rb │ ├── so_ackermann.rb │ ├── so_array.rb │ ├── so_binary_trees.rb │ ├── so_concatenate.rb │ ├── so_count_words.yml │ ├── so_exception.rb │ ├── so_fannkuch.rb │ ├── so_fasta.rb │ ├── so_k_nucleotide.yml │ ├── so_lists.rb │ ├── so_mandelbrot.rb │ ├── so_matrix.rb │ ├── so_meteor_contest.rb │ ├── so_nbody.rb │ ├── so_nested_loop.rb │ ├── so_nsieve.rb │ ├── so_nsieve_bits.rb │ ├── so_object.rb │ ├── so_partial_sums.rb │ ├── so_pidigits.rb │ ├── so_random.rb │ ├── so_reverse_complement.yml │ ├── so_sieve.rb │ ├── so_spectralnorm.rb │ ├── string_capitalize.yml │ ├── string_downcase.yml │ ├── string_index.rb │ ├── string_scan_re.rb │ ├── string_scan_str.rb │ ├── string_split.yml │ ├── string_swapcase.yml │ ├── string_upcase.yml │ ├── time_strptime.yml │ ├── time_subsec.rb │ ├── vm1_attr_ivar.yml │ ├── vm1_attr_ivar_set.yml │ ├── vm1_block.yml │ ├── vm1_blockparam.yml │ ├── vm1_blockparam_call.yml │ ├── vm1_blockparam_pass.yml │ ├── vm1_blockparam_yield.yml │ ├── vm1_const.yml │ ├── vm1_ensure.yml │ ├── vm1_float_simple.yml │ ├── vm1_gc_short_lived.yml │ ├── vm1_gc_short_with_complex_long.yml │ ├── vm1_gc_short_with_long.yml │ ├── vm1_gc_short_with_symbol.yml │ ├── vm1_gc_wb_ary.yml │ ├── vm1_gc_wb_ary_promoted.yml │ ├── vm1_gc_wb_obj.yml │ ├── vm1_gc_wb_obj_promoted.yml │ ├── vm1_ivar.yml │ ├── vm1_ivar_set.yml │ ├── vm1_length.yml │ ├── vm1_lvar_init.yml │ ├── vm1_lvar_set.yml │ ├── vm1_neq.yml │ ├── vm1_not.yml │ ├── vm1_rescue.yml │ ├── vm1_simplereturn.yml │ ├── vm1_swap.yml │ ├── vm1_yield.yml │ ├── vm2_array.yml │ ├── vm2_bigarray.yml │ ├── vm2_bighash.yml │ ├── vm2_case.yml │ ├── vm2_case_lit.yml │ ├── vm2_defined_method.yml │ ├── vm2_dstr.yml │ ├── vm2_eval.yml │ ├── vm2_fiber_allocate.yml │ ├── vm2_fiber_count.yml │ ├── vm2_fiber_reuse.yml │ ├── vm2_fiber_reuse_gc.yml │ ├── vm2_fiber_switch.yml │ ├── vm2_freezestring.yml │ ├── vm2_method.yml │ ├── vm2_method_missing.yml │ ├── vm2_method_with_block.yml │ ├── vm2_module_ann_const_set.yml │ ├── vm2_module_const_set.yml │ ├── vm2_mutex.yml │ ├── vm2_newlambda.yml │ ├── vm2_poly_method.yml │ ├── vm2_poly_method_ov.yml │ ├── vm2_poly_singleton.yml │ ├── vm2_proc.yml │ ├── vm2_raise1.yml │ ├── vm2_raise2.yml │ ├── vm2_regexp.yml │ ├── vm2_send.yml │ ├── vm2_string_literal.yml │ ├── vm2_struct_big_aref_hi.yml │ ├── vm2_struct_big_aref_lo.yml │ ├── vm2_struct_big_aset.yml │ ├── vm2_struct_big_href_hi.yml │ ├── vm2_struct_big_href_lo.yml │ ├── vm2_struct_big_hset.yml │ ├── vm2_struct_small_aref.yml │ ├── vm2_struct_small_aset.yml │ ├── vm2_struct_small_href.yml │ ├── vm2_struct_small_hset.yml │ ├── vm2_super.yml │ ├── vm2_unif1.yml │ ├── vm2_zsuper.yml │ ├── vm3_backtrace.rb │ ├── vm3_clearmethodcache.rb │ ├── vm3_gc.rb │ ├── vm3_gc_old_full.rb │ ├── vm3_gc_old_immediate.rb │ ├── vm3_gc_old_lazy.rb │ ├── vm_symbol_block_pass.rb │ ├── vm_thread_alive_check.yml │ ├── vm_thread_alive_check1.rb │ ├── vm_thread_close.rb │ ├── vm_thread_condvar1.rb │ ├── vm_thread_condvar2.rb │ ├── vm_thread_create_join.rb │ ├── vm_thread_mutex1.rb │ ├── vm_thread_mutex2.rb │ ├── vm_thread_mutex3.rb │ ├── vm_thread_pass.rb │ ├── vm_thread_pass_flood.rb │ ├── vm_thread_pipe.rb │ ├── vm_thread_queue.rb │ ├── vm_thread_sized_queue.rb │ ├── vm_thread_sized_queue2.rb │ ├── vm_thread_sized_queue3.rb │ ├── vm_thread_sized_queue4.rb │ └── vm_thread_sleep.yml └── driver.rb ├── sequel ├── .bundle │ └── config ├── Gemfile └── benchmarks │ ├── bm_sequel_create_string_columns.rb │ ├── bm_sequel_destroy.rb │ ├── bm_sequel_discourse.rb │ ├── bm_sequel_finders_find_by_attributes.rb │ ├── bm_sequel_finders_find_by_attributes_over_select.rb │ ├── bm_sequel_finders_first.rb │ ├── bm_sequel_finders_first_over_select.rb │ ├── bm_sequel_save.rb │ ├── bm_sequel_scope_all.rb │ ├── bm_sequel_scope_all_over_select.rb │ ├── bm_sequel_scope_all_with_default_scope.rb │ ├── bm_sequel_scope_all_with_default_scope_over_select.rb │ ├── bm_sequel_scope_where.rb │ ├── bm_sequel_scope_where_over_select.rb │ ├── bm_sequel_validations_invalid.rb │ ├── bm_sequel_validations_valid.rb │ ├── driver.rb │ └── support │ └── benchmark_sequel.rb ├── suite-logo.png └── support ├── benchmark_runner.rb ├── helpers.rb └── setup ├── .bundle └── config ├── Gemfile ├── bm_create_string_columns_setup.rb ├── bm_destroy_setup.rb ├── bm_discourse_setup.rb ├── bm_finders_setup.rb ├── bm_preload_setup.rb ├── bm_save_setup.rb ├── bm_scope_all_setup.rb ├── bm_scope_where_setup.rb ├── bm_validations_invalid_setup.rb ├── bm_validations_valid_setup.rb └── bm_with_default_scope_setup.rb /.byebug_history: -------------------------------------------------------------------------------- 1 | exit 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | rails/vendor/ 2 | rails/log/ 3 | Gemfile.lock 4 | sequel/vendor/ 5 | sequel/log/ 6 | support/setup/vendor 7 | 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "optcarrot_benchmarks/optcarrot"] 2 | path = optcarrot_benchmarks/optcarrot 3 | url = https://github.com/mame/optcarrot.git 4 | [submodule "liquid_benchmarks/liquid"] 5 | path = liquid_benchmarks/liquid 6 | url = https://github.com/Shopify/liquid.git 7 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. 10 | 11 | This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. 12 | 13 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 14 | 15 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.1.0, available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/) 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ruby-bench 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ruby Bench Benchmark Suite 2 | 3 | ![ruby bench suite](suite-logo.png) 4 | 5 | This repository contains the benchmarks that are being run on [RubyBench.org](http://rubybench.org/). 6 | 7 | For overall project description visit [ruby-bench/ruby-bench](https://github.com/ruby-bench/ruby-bench) repo. 8 | 9 | ## Benchmarked projects 10 | Suite currently includes benchmarks for following projects: 11 | - [Ruby](https://github.com/ruby/ruby) 12 | - [Rails](https://github.com/rails/rails) 13 | - [Bundler](https://github.com/bundler/bundler) 14 | - [Sequel](https://github.com/jeremyevans/sequel) 15 | - [Discourse](https://github.com/discourse/discourse) 16 | - [Liquid](https://github.com/Shopify/liquid) 17 | - [Optcarrot](https://github.com/mame/optcarrot) 18 | 19 | ## Contribute 20 | 21 | See `guides/` to learn how you can run and create Rails benchmarks. 22 | 23 | Simply open a pull request to contribute a benchmark to this suite. 24 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } 4 | 5 | # Specify your gem's dependencies in benchmark_driver-output-rubybench.gemspec 6 | gemspec 7 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Takashi Kokubun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/README.md: -------------------------------------------------------------------------------- 1 | # BenchmarkDriver::Output::Rubybench 2 | 3 | Use this with `gem install benchmark_driver-output-rubybench` on ruby-bench-docker. 4 | 5 | ## License 6 | 7 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 8 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | task :default => :spec 3 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/benchmark_driver-output-rubybench.gemspec: -------------------------------------------------------------------------------- 1 | 2 | lib = File.expand_path("../lib", __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require "benchmark_driver/output/rubybench/version" 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "benchmark_driver-output-rubybench" 8 | spec.version = BenchmarkDriver::Output::Rubybench::VERSION 9 | spec.authors = ["Takashi Kokubun"] 10 | spec.email = ["takashikkbn@gmail.com"] 11 | 12 | spec.summary = %q{benchmark_driver plugin to output result to RubyBench} 13 | spec.description = %q{benchmark_driver plugin to output result to RubyBench} 14 | spec.homepage = "https://github.com/ruby-bench/ruby-bench-suite" 15 | spec.license = "MIT" 16 | 17 | # Specify which files should be added to the gem when it is released. 18 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 19 | spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do 20 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 21 | end 22 | spec.bindir = "exe" 23 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 24 | spec.require_paths = ["lib"] 25 | 26 | spec.add_dependency "benchmark_driver", ">= 0.12" 27 | spec.add_development_dependency "bundler", "~> 1.16" 28 | spec.add_development_dependency "rake", "~> 10.0" 29 | end 30 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/lib/benchmark_driver/output/rubybench/version.rb: -------------------------------------------------------------------------------- 1 | module BenchmarkDriver 2 | module Output 3 | class Rubybench 4 | VERSION = "0.3.1" 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /benchmark_driver-output-rubybench/lib/benchmark_driver/runner/seconds.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark_driver/runner/time' 2 | 3 | # For having a metric label compatible with RubyBench 4 | class BenchmarkDriver::Runner::Seconds < BenchmarkDriver::Runner::Time 5 | METRIC = BenchmarkDriver::Metric.new(name: 'Execution time', unit: 'Seconds', larger_better: false) 6 | 7 | # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" 8 | Job = Class.new(BenchmarkDriver::DefaultJob) 9 | # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` 10 | JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) 11 | 12 | # Overriding BenchmarkDriver::Runner::Ips#metric 13 | def metric 14 | METRIC 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_exec_binary.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | noop_gem = Pathname(__FILE__).expand_path + '../gems/noop-gem' 5 | 6 | Dir.mktmpdir do |dir| 7 | Dir.chdir(dir) do 8 | File.write('Gemfile', <<-GEMFILE) 9 | source 'https://rubygems.org' 10 | gem 'rails' 11 | gem 'noop-gem', path: '#{noop_gem}' 12 | GEMFILE 13 | system("bundle install --quiet") 14 | 15 | Benchmark.do_benchmark('bundle exec binary') do 16 | system("bundle exec true") 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_exec_gem.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | noop_gem = Pathname(__FILE__).expand_path + '../gems/noop-gem' 5 | 6 | Dir.mktmpdir do |dir| 7 | Dir.chdir(dir) do 8 | File.write('Gemfile', <<-GEMFILE) 9 | source 'https://rubygems.org' 10 | gem 'rails' 11 | gem 'noop-gem', path: '#{noop_gem}' 12 | GEMFILE 13 | system("bundle install --quiet") 14 | 15 | Benchmark.do_benchmark('bundle exec gem') do 16 | system("bundle exec noop-gem") 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_exec_shell.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | noop_gem = Pathname(__FILE__).expand_path + '../gems/noop-gem' 5 | 6 | Dir.mktmpdir do |dir| 7 | Dir.chdir(dir) do 8 | File.write('Gemfile', <<-GEMFILE) 9 | source 'https://rubygems.org' 10 | gem 'rails' 11 | gem 'noop-gem', path: '#{noop_gem}' 12 | GEMFILE 13 | system("bundle install --quiet") 14 | 15 | Benchmark.do_benchmark('bundle exec shell') do 16 | system("bundle exec 'noop-gem foo bar'") 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_install_rails.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | # Fixed Nokogiri version because latest version 1.6.8 fails to install 5 | 6 | Dir.mktmpdir do |dir| 7 | Dir.chdir(dir) do 8 | File.write('Gemfile', <<-GEMFILE) 9 | source 'https://rubygems.org' 10 | gem 'rails' 11 | gem 'nokogiri', '1.6.7.2' 12 | GEMFILE 13 | 14 | system("bundle package --quiet") 15 | system("bundle install --quiet") 16 | 17 | Benchmark.do_benchmark('bundle install rails', time: 60) do 18 | system("bundle install --quiet") 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_install_rails_fixed.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | Dir.mktmpdir do |dir| 5 | Dir.chdir(dir) do 6 | File.write('Gemfile', <<-GEMFILE) 7 | source 'https://rubygems.org' 8 | gem 'rails', '5.0.0' 9 | gem 'nokogiri', '1.6.7.2' 10 | GEMFILE 11 | 12 | system("bundle package --quiet") 13 | system("bundle install --quiet") 14 | 15 | Benchmark.do_benchmark('bundle install rails fixed', time: 60) do 16 | system("bundle install --quiet") 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_lock_gem.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | noop_gem = Pathname(__FILE__).expand_path + '../gems/noop-gem' 5 | 6 | Dir.mktmpdir do |dir| 7 | Dir.chdir(dir) do 8 | File.write('Gemfile', <<-GEMFILE) 9 | source 'https://rubygems.org' 10 | gem 'rails' 11 | gem 'noop-gem', path: '#{noop_gem}' 12 | GEMFILE 13 | 14 | system("bundle lock") 15 | 16 | Benchmark.do_benchmark('bundle lock') do 17 | system("bundle lock") 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_bundle_outdated_rails.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | require 'bundler/cli' 3 | 4 | Dir.mktmpdir do |dir| 5 | Dir.chdir(dir) do 6 | File.write('Gemfile', <<-GEMFILE) 7 | source 'https://rubygems.org' 8 | gem 'rails', '5.0.0.rc1' 9 | gem 'nokogiri', '1.6.7.0' 10 | GEMFILE 11 | 12 | system("bundle install --quiet") 13 | system("bundle outdated --quiet") 14 | 15 | Benchmark.do_benchmark('bundle outdated rails') do 16 | system("bundle outdated --quiet") 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_resolve_cocoapods.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | 3 | gemfile = proc do 4 | source :rubygems 5 | gem 'cocoapods' 6 | end 7 | 8 | Benchmark.resolve_definition('cocoapods', gemfile) 9 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_resolve_gx_api_rails.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | 3 | gemfile = proc do 4 | source "https://rubygems.org" 5 | 6 | gem "sass-rails" 7 | gem "rails", "~> 3" 8 | gem "gxapi_rails" 9 | end 10 | 11 | Benchmark.resolve_definition('gxapi_rails', gemfile) 12 | -------------------------------------------------------------------------------- /bundler/benchmarks/bm_resolve_rails.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/benchmark_bundler.rb' 2 | 3 | gemfile = proc do 4 | source :rubygems 5 | gem 'rails' 6 | end 7 | 8 | Benchmark.resolve_definition('rails', gemfile) 9 | -------------------------------------------------------------------------------- /bundler/benchmarks/gems/noop-gem/bin/noop-gem: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'rails' 4 | exit 0 5 | -------------------------------------------------------------------------------- /bundler/benchmarks/gems/noop-gem/lib/noop/gem.rb: -------------------------------------------------------------------------------- 1 | require "noop/gem/version" 2 | 3 | module Noop 4 | module Gem 5 | # Your code goes here... 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /bundler/benchmarks/gems/noop-gem/lib/noop/gem/version.rb: -------------------------------------------------------------------------------- 1 | module Noop 2 | module Gem 3 | VERSION = "0.1.0" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /bundler/benchmarks/gems/noop-gem/noop-gem.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'noop/gem/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "noop-gem" 8 | spec.version = Noop::Gem::VERSION 9 | spec.authors = ["Samuel E. Giddins"] 10 | spec.email = ["segiddins@segiddins.me"] 11 | spec.summary = '' 12 | 13 | spec.files = Dir["{lib,bin}/**/*"] 14 | spec.bindir = "bin" 15 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 16 | spec.require_paths = ["lib"] 17 | 18 | spec.add_development_dependency "bundler", "~> 1.10" 19 | spec.add_development_dependency "rake", "~> 10.0" 20 | end 21 | -------------------------------------------------------------------------------- /bundler/benchmarks/support/benchmark_bundler.rb: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | require 'benchmark/ips' 3 | require 'json' 4 | require 'tempfile' 5 | 6 | ENV['BUNDLE_GEMFILE'] = 'Gemfile' 7 | 8 | rubygems = Bundler.rubygems 9 | def rubygems.validate(spec); end 10 | 11 | # Bundler.ui = Bundler::UI::Shell.new 12 | 13 | module Benchmark 14 | module Bundler 15 | module Resolver 16 | def resolve_definition(label, gemfile, lockfile: nil, unlock: true, git_gems: {}) 17 | builder = ::Bundler::Dsl.new 18 | builder.instance_eval(&gemfile) 19 | if lockfile 20 | tmp_lockfile = Tempfile.new("#{label}_lockfile") 21 | tmp_lockfile.write lockfile 22 | lockfile = tmp_lockfile.path 23 | end 24 | unlock = { gems: unlock } if Array === unlock 25 | definition = builder.to_definition(lockfile, unlock) 26 | 27 | definition.send(:sources).git_sources.each do |s| 28 | if specs = git_gems[s.to_s] 29 | s.define_singleton_method(:specs) do 30 | @specs ||= begin 31 | ::Bundler::Index.build do |idx| 32 | idx.use Array(specs) 33 | end 34 | end 35 | end 36 | end 37 | end 38 | 39 | definition.resolve_remotely! 40 | 41 | block = proc do 42 | definition.instance_variable_set(:@specs, nil) 43 | definition.instance_variable_set(:@resolve, nil) 44 | definition.specs 45 | end 46 | 47 | do_benchmark(label, &block) 48 | end 49 | 50 | def do_benchmark(label, time: 20, warmup: 7, &block) 51 | report = Benchmark.ips(time, warmup, true) do |bm| 52 | bm.report(label, &block) 53 | end 54 | 55 | entry = report.entries.first 56 | output = JSON.pretty_generate({ 57 | label: label, 58 | version: ::Bundler::VERSION, 59 | iterations_per_second: entry.ips, 60 | iterations_per_second_standard_deviation: entry.stddev_percentage, 61 | total_allocated_objects_per_iteration: get_total_allocated_objects(&block), 62 | }) 63 | 64 | puts output 65 | end 66 | 67 | def get_total_allocated_objects 68 | if block_given? 69 | key = 70 | if RUBY_VERSION < '2.2' 71 | :total_allocated_object 72 | else 73 | :total_allocated_objects 74 | end 75 | 76 | before = GC.stat[key] 77 | yield 78 | after = GC.stat[key] 79 | after - before 80 | end 81 | end 82 | end 83 | end 84 | 85 | extend Bundler::Resolver 86 | end 87 | -------------------------------------------------------------------------------- /discourse/benchmarks/patches/active_support_duration.rb: -------------------------------------------------------------------------------- 1 | # https://github.com/rails/rails/issues/21296 2 | # https://bugs.ruby-lang.org/issues/11465 3 | # This has been fixed in Rails 4.2 but we run Ruby trunk benchmarks against Discourse 4 | # on Rails 4.1 5 | module ActiveSupport 6 | refine Duration do 7 | def respond_to_missing?(method, include_private=false) 8 | @value.respond_to?(method, include_private) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /discourse/rails_ruby_bench/patches/assets_jq.rb: -------------------------------------------------------------------------------- 1 | # Minor bugfix for earlier version of Discourse. Can remove when I only use 1.8.0+ Discourse? 2 | Rails.application.config.assets.precompile += %w( jquery_include.js ) 3 | -------------------------------------------------------------------------------- /guides/running_and_writing_rails_benchmarks.md: -------------------------------------------------------------------------------- 1 | # Running benchmarks locally 2 | 3 | 1. `RAILS_MASTER=1 bundle install` 4 | 2. To run rails benchmarks in mysql2 : `RAILS_MASTER=1 DATABASE_URL=mysql2://root@'localhost':3306/rubybench ruby benchmarks/bm_activerecord_destroy.rb` 5 | 6 | To run rails benchmarks in postgres : `RAILS_MASTER=1 DATABASE_URL=postgres://postgres@'localhost':5432/rubybench ruby benchmarks/bm_activerecord_destroy.rb` 7 | 8 | Specify your file instead of `bm_activerecord_destroy.rb`.`DATABASE_URL` key is required when running ActiveRecord benchmarks. 9 | 10 | 3. Benchmark result will be printed as JSON. 11 | 12 | # Adding new Rails benchmarks 13 | 14 | Let's look at the sample Sprockets bench: 15 | 16 | ```ruby 17 | require 'bundler/setup' 18 | 19 | # we will use benchmark helper 20 | require_relative 'support/benchmark_rails' 21 | require 'sprockets' 22 | require 'rack/builder' 23 | 24 | app = Rack::Builder.new do 25 | map "/assets" do 26 | environment = Sprockets::Environment.new 27 | environment.append_path File.expand_path('../assets/javascripts', __FILE__) 28 | run environment 29 | end 30 | end 31 | request = Rack::MockRequest.env_for("/assets/application.js") 32 | 33 | # pass benchmarkable code to the block. 34 | # Benchmark.rails accepts benchmark key and duration in seconds. 35 | Benchmark.rails("sprockets/simple", time: 5) do 36 | response = app.call(request) 37 | # assert that response code is successful 38 | raise "Request failed" unless response[0] == 200 39 | end 40 | ``` 41 | -------------------------------------------------------------------------------- /liquid_benchmarks/benchmark_liquid.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark/ips' 2 | require 'json' 3 | 4 | require_relative '../support/benchmark_runner' 5 | 6 | module Benchmark 7 | module Liquid 8 | def liquid(label=nil, version: ::Liquid::VERSION.to_s, time: 10, disable_gc: false, warmup: 5, &block) 9 | Benchmark::Runner.run(label, version: version, time: time, disable_gc: disable_gc, warmup: warmup, &block) 10 | end 11 | end 12 | 13 | extend Benchmark::Liquid 14 | end 15 | -------------------------------------------------------------------------------- /liquid_benchmarks/bm_parse.rb: -------------------------------------------------------------------------------- 1 | require_relative 'benchmark_liquid' 2 | require_relative 'liquid/performance/theme_runner' 3 | 4 | profiler = ThemeRunner.new 5 | 6 | Benchmark.liquid("parse") do 7 | profiler.compile 8 | end 9 | -------------------------------------------------------------------------------- /liquid_benchmarks/bm_parse_and_render.rb: -------------------------------------------------------------------------------- 1 | require_relative 'benchmark_liquid' 2 | require_relative 'liquid/performance/theme_runner' 3 | 4 | profiler = ThemeRunner.new 5 | 6 | Benchmark.liquid("parse_and_render") do 7 | profiler.run 8 | end 9 | -------------------------------------------------------------------------------- /liquid_benchmarks/bm_render.rb: -------------------------------------------------------------------------------- 1 | require_relative 'benchmark_liquid' 2 | require_relative 'liquid/performance/theme_runner' 3 | 4 | profiler = ThemeRunner.new 5 | 6 | Benchmark.liquid("render") do 7 | profiler.render 8 | end 9 | -------------------------------------------------------------------------------- /optcarrot_benchmarks/driver.rb: -------------------------------------------------------------------------------- 1 | require 'digest' 2 | require_relative 'optcarrot/lib/optcarrot' 3 | 4 | ENV['BENCHMARK_TYPE_SCRIPT_URL'] = 'https://raw.githubusercontent.com/mame/optcarrot/master/lib/optcarrot/nes.rb' 5 | ENV['BENCHMARK_TYPE_DIGEST'] = Digest::SHA2.hexdigest(Optcarrot::VERSION) 6 | ENV['REPO_NAME'] = 'ruby' 7 | ENV['ORGANIZATION_NAME'] = 'ruby' 8 | 9 | ruby_options = ['-e', "default::#{RbConfig.ruby}"] 10 | if Gem::Version.new(`ruby -e "puts RUBY_VERSION"`.chomp) >= Gem::Version.new('2.6.0') 11 | ruby_options.concat(['-e', "default_jit::#{RbConfig.ruby} --jit"]) 12 | end 13 | 14 | benchmark_yml = File.expand_path('./optcarrot/benchmark.yml', __dir__) 15 | exec 'benchmark-driver', benchmark_yml, '-o', 'rubybench', *ruby_options, \ 16 | '--repeat-count', '3', '--repeat-result', 'average' 17 | -------------------------------------------------------------------------------- /pg/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | module ::Kernel 4 | def pg_master? 5 | ENV["PG_MASTER"] == '1' 6 | end 7 | end 8 | 9 | if pg_master? 10 | gem 'pg', github: 'ged/ruby-pg' 11 | else 12 | gem 'pg', path: '/ruby-pg' 13 | end 14 | 15 | gem 'benchmark-ips', '~> 2.2.0' 16 | gem 'byebug' 17 | -------------------------------------------------------------------------------- /pg/benchmarks/bm_discourse.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'pg' 3 | require 'byebug' 4 | require 'time' 5 | 6 | require_relative 'support/benchmark_pg' 7 | 8 | db_setup script: "bm_discourse_setup.rb" 9 | 10 | conn = PG.connect(ENV.fetch("DATABASE_URL")) 11 | 12 | user = conn.exec("SELECT * FROM users ORDER BY users.id LIMIT 1").first 13 | Benchmark.pg("pg/discourse", time: 5) do 14 | str = "" 15 | 16 | topics = conn.exec( 17 | " 18 | SELECT 19 | topics.id, 20 | topics.created_at, 21 | topics.updated_at, 22 | topics.title, 23 | topics.bumped_at, 24 | topics.archetype, 25 | topics.deleted_at, 26 | topics.pinned_globally, 27 | topics.pinned_at, 28 | topics.user_id, 29 | topics.category_id, 30 | categories.id, 31 | categories.created_at, 32 | categories.updated_at, 33 | categories.topic_id 34 | FROM topics 35 | LEFT OUTER JOIN categories ON categories.id = topics.category_id 36 | LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user['id']}) 37 | WHERE ( 38 | (topics.archetype <> 'private_message') 39 | AND (COALESCE(categories.topic_id, 0) <> topics.id) 40 | AND (topics.deleted_at IS NULL) 41 | AND ( 42 | NOT EXISTS ( 43 | SELECT 1 FROM category_users cu 44 | WHERE cu.user_id = #{user['id']} 45 | AND cu.category_id = topics.category_id 46 | AND cu.notification_level = 0 47 | AND cu.category_id <> -1 48 | AND (tu.notification_level IS NULL OR tu.notification_level < 2) 49 | ) 50 | ) 51 | AND ( 52 | pinned_globally 53 | AND pinned_at IS NOT NULL 54 | AND (topics.pinned_at > tu.cleared_pinned_at OR tu.cleared_pinned_at IS NULL) 55 | ) 56 | ) 57 | ORDER BY topics.bumped_at 58 | DESC 59 | LIMIT 30 60 | " 61 | ) 62 | 63 | # Preload users 64 | conn.exec("SELECT users.* FROM users WHERE users.id IN (#{user['id']})") 65 | 66 | topics.each_row do |topic| 67 | str << "id: #{topic[0]} title: #{topic[3]} created_at: #{Time.parse(topic[1]).iso8601} user: #{user['username']}\n" 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /pg/benchmarks/bm_scope_all.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'pg' 3 | require_relative 'support/benchmark_pg' 4 | 5 | db_setup script: "bm_scope_all_setup.rb" 6 | 7 | connection = PG.connect(ENV.fetch("DATABASE_URL")) 8 | type_mapper = PG::BasicTypeMapForResults.new(connection) 9 | 10 | Benchmark.pg("pg/scope_all", time: 5) do 11 | str = "" 12 | 13 | result = connection.exec("SELECT name, email, approved, age, birthday FROM users") 14 | result.type_map = type_mapper 15 | 16 | i = 0 17 | while i < result.ntuples do 18 | str << "name: #{result.getvalue(i, 0)} email: #{result.getvalue(i, 1)} approved: #{result.getvalue(i, 2)} age: #{result.getvalue(i, 3)} birthday: #{result.getvalue(i, 4)} \n" 19 | i += 1 20 | end 21 | end 22 | 23 | -------------------------------------------------------------------------------- /pg/benchmarks/bm_scope_all_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'pg' 3 | require_relative 'support/benchmark_pg' 4 | 5 | db_setup script: "bm_scope_all_setup.rb" 6 | 7 | connection = PG.connect(ENV.fetch("DATABASE_URL")) 8 | type_mapper = PG::BasicTypeMapForResults.new(connection) 9 | 10 | Benchmark.pg("pg/scope_all_over_select", time: 5) do 11 | str = "" 12 | 13 | result = connection.exec("SELECT * FROM users") 14 | result.type_map = type_mapper 15 | 16 | i = 0 17 | while i < result.ntuples do 18 | str << "name: #{result.getvalue(i, 0)} email: #{result.getvalue(i, 1)} approved: #{result.getvalue(i, 2)} age: #{result.getvalue(i, 3)} birthday: #{result.getvalue(i, 4)} \n" 19 | i += 1 20 | end 21 | end 22 | 23 | -------------------------------------------------------------------------------- /pg/benchmarks/driver.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'optparse' 3 | require_relative 'pg_suite_runner' 4 | 5 | options = { 6 | pattern: [] 7 | } 8 | 9 | OptionParser.new do |opts| 10 | opts.banner = 'Usage: ruby driver.rb [options]' 11 | 12 | opts.on('-p', '--pattern ', 'Benchmark name pattern') do |value| 13 | options[:pattern] = value.split(',') 14 | end 15 | end.parse!(ARGV) 16 | 17 | PGSuiteRunner.run(options) 18 | -------------------------------------------------------------------------------- /pg/benchmarks/support/benchmark_pg.rb: -------------------------------------------------------------------------------- 1 | require 'pg' 2 | 3 | require_relative '../../../support/benchmark_runner' 4 | require_relative '../../../support/helpers' 5 | 6 | module Benchmark 7 | module PG 8 | def pg(label = nil, version: ::PG::VERSION.to_s, time:, disable_gc: true, warmup: 3, &block) 9 | Benchmark::Runner.run(label, version: version, time: time, disable_gc: disable_gc, warmup: warmup, &block) 10 | end 11 | end 12 | 13 | extend Benchmark::PG 14 | end 15 | -------------------------------------------------------------------------------- /rails/.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_PATH: "vendor/bundle" 3 | BUNDLE_DISABLE_SHARED_GEMS: "true" 4 | BUNDLE_JOBS: "4" 5 | -------------------------------------------------------------------------------- /rails/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | module ::Kernel 4 | def rails_master? 5 | ENV["RAILS_MASTER"] == '1' 6 | end 7 | 8 | def skip_rails? 9 | ENV["SKIP_RAILS"] == '1' 10 | end 11 | 12 | def mysql2_prepared_statements? 13 | ENV["MYSQL2_PREPARED_STATEMENTS"] == '1' 14 | end 15 | 16 | def v_4_0_x? 17 | major, minor, micro = ENV["RAILS_VERSION"].to_s.split(".") 18 | major == "4" && minor == "0" 19 | end 20 | end 21 | 22 | if rails_master? 23 | gem 'arel', github: 'rails/arel', branch: 'master' 24 | gem 'rails', github: 'rails' 25 | gem 'rack', github: 'rack/rack', branch: 'master' 26 | gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master' 27 | gem 'sprockets', github: 'rails/sprockets', branch: 'master' 28 | gem 'jquery-rails', github: 'rails/jquery-rails', branch: 'master' 29 | gem 'mail', github: 'mikel/mail', branch: 'master' 30 | gem 'globalid', github: 'rails/globalid', branch: 'master' 31 | gem 'sass-rails', github: 'rails/sass-rails', branch: 'master' 32 | gem 'turbolinks', github: 'turbolinks/turbolinks-rails', branch: 'master' 33 | elsif !skip_rails? 34 | gem 'rails', path: '/rails' 35 | end 36 | 37 | if mysql2_prepared_statements? 38 | # Does not work with < Rails 4.2.5. 39 | # See http://github.com/rails/rails/issues/21544. 40 | gem 'mysql2', '0.4.6' 41 | else 42 | gem 'mysql2', '0.3.18' 43 | end 44 | 45 | unless v_4_0_x? 46 | gem 'tzinfo-data', '~> 1.2' 47 | end 48 | 49 | gem 'pg', '0.18.1' 50 | gem 'benchmark-ips', '~> 2.2.0' 51 | gem 'redis', '~> 3.0' 52 | gem 'puma', '~> 3.12.1' 53 | -------------------------------------------------------------------------------- /rails/benchmarks/actionpack_router.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | 3 | require 'rails' 4 | require 'action_controller/railtie' 5 | 6 | require_relative 'support/benchmark_rails.rb' 7 | 8 | class NullLogger < Logger 9 | def initialize(*args) 10 | end 11 | 12 | def add(*args, &block) 13 | end 14 | end 15 | 16 | class BenchmarkApp < Rails::Application 17 | routes.append do 18 | namespace :editor do 19 | resources :professionals 20 | resource :message 21 | end 22 | 23 | scope path: '/prices' do 24 | get 'info' => 'prices#info' 25 | end 26 | 27 | scope '/coupon' do 28 | get 'some' => 'coupons#some' 29 | end 30 | 31 | root to: "home#index" 32 | 33 | resources :topics do 34 | resources :messages do 35 | resources :likes 36 | end 37 | end 38 | 39 | resources :professionals, only: [:index] do 40 | collection do 41 | match 'category/:specialization_id', to: 'professionals#by_category', as: 'by_category', via: [:get, :post] 42 | end 43 | end 44 | 45 | get "/listings/:any" => redirect("/properties/%{any}") 46 | 47 | get 'system/*path', to: proc {|env| [404, {}, []] } 48 | constraints id: /\d+(.*)/ do 49 | get '/zagorodnaya/*addressing_slug/:id', 50 | to: 'developments#show', 51 | as: :residential_seo 52 | end 53 | end 54 | config.secret_token = "s"*30 55 | config.secret_key_base = 'foo' 56 | config.consider_all_requests_local = false 57 | 58 | # simulate production 59 | config.cache_classes = true 60 | config.eager_load = true 61 | config.action_controller.perform_caching = true 62 | 63 | # otherwise deadlock occured 64 | config.middleware.delete "Rack::Lock" 65 | 66 | # to disable log files 67 | config.logger = NullLogger.new 68 | config.active_support.deprecation = :log 69 | end 70 | 71 | class ProfessionalsController < ActionController::Base 72 | def index 73 | render text: "Hello!" 74 | end 75 | 76 | def by_category 77 | render text: "Hello!" 78 | end 79 | end 80 | 81 | class HomeController < ActionController::Base 82 | def index 83 | render text: "Hello!" 84 | end 85 | end 86 | 87 | class LikesController < ActionController::Base 88 | def index 89 | render text: "likes index" 90 | end 91 | 92 | def show 93 | render text: "likes show" 94 | end 95 | end 96 | 97 | BenchmarkApp.initialize! 98 | 99 | class RouteNotFoundError < StandardError;end 100 | 101 | def request(method, path) 102 | response = Rack::MockRequest.new(BenchmarkApp).send(method, path) 103 | if response.status.in?([404, 500]) 104 | raise RouteNotFoundError.new, "not found #{method.to_s.upcase} #{path}" 105 | end 106 | response 107 | end 108 | 109 | Benchmark.rails("actionpack_router", time: 10) do 110 | request(:get, "/") 111 | request(:get, "/topics/1/messages/1/likes/") 112 | 113 | request(:get, "/topics/1/messages/1/likes/1") 114 | 115 | request(:get, "/listings/complicated") 116 | request(:post, "/professionals/category/first") 117 | request(:get, "/professionals/category/first") 118 | end 119 | -------------------------------------------------------------------------------- /rails/benchmarks/actionpack_url_generation_others.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/url_generation_base.rb' 2 | require_relative 'support/benchmark_rails.rb' 3 | 4 | Benchmark.rails("actionpack_url_generation_others", time: 10) do 5 | router = Router.new 6 | 7 | router.listing_redirect_path(:any) 8 | router.residential_path(id: 2, addressing_slug: 'brooklyn') 9 | router.by_category_professionals_path(2) 10 | end 11 | -------------------------------------------------------------------------------- /rails/benchmarks/actionpack_url_generation_rest.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/url_generation_base.rb' 2 | require_relative 'support/benchmark_rails.rb' 3 | 4 | Benchmark.rails("actionpack_url_generation_rest", time: 10) do 5 | router = Router.new 6 | 7 | router.topic_path(2) 8 | router.edit_topic_path(2) 9 | router.edit_topic_message_path(1, 2) 10 | router.new_topic_message_path(1, 2) 11 | router.topic_message_path(1, 2) 12 | 13 | router.topic_message_like_path(1, 2, 3) 14 | router.edit_topic_message_like_path(1, 2, 3) 15 | router.new_topic_message_like_path(1, 2, 3) 16 | end 17 | -------------------------------------------------------------------------------- /rails/benchmarks/actionpack_url_generation_url_for.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/url_generation_base.rb' 2 | require_relative 'support/benchmark_rails.rb' 3 | 4 | Benchmark.rails("actionpack_url_generation_url_for", time: 10) do 5 | router = Router.new 6 | 7 | router.url_for(controller: 'prices', action: 'info') 8 | router.url_for(controller: 'coupons', action: 'some') 9 | router.url_for(controller: 'professionals', action: 'index') 10 | end 11 | -------------------------------------------------------------------------------- /rails/benchmarks/actionview_partials.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | 3 | require 'ffaker' 4 | 5 | require 'rails' 6 | require 'action_controller/railtie' 7 | 8 | require_relative 'support/benchmark_rails.rb' 9 | 10 | class HeavyController < ActionController::Base 11 | def index 12 | end 13 | end 14 | 15 | class HeavyView < ActionView::Base 16 | end 17 | 18 | Post = Struct.new(:id) do 19 | def title 20 | Faker::Name.name 21 | end 22 | 23 | def from 24 | Faker::AddressFI.city 25 | end 26 | 27 | def body 28 | Faker::HipsterIpsum.words(50).join(" ") 29 | end 30 | end 31 | 32 | User = Struct.new(:id) do 33 | def email 34 | Faker::Internet.email 35 | end 36 | end 37 | 38 | def render_views 39 | controller = HeavyController.new 40 | controller.request = ActionDispatch::Request.new({}) 41 | 42 | current = File.expand_path File.dirname(__FILE__) 43 | view = HeavyView.new("#{current}/partials", {}, controller) 44 | 45 | locals = { 46 | records: 3, 47 | posts: (1..50).to_a.map { |a| Post.new(a) }, 48 | users: (1..50).to_a.map { |a| User.new(a) }, 49 | } 50 | view.render(template: "first", layout: "layouts/application", locals: locals) 51 | end 52 | 53 | Benchmark.rails("actionview_render_partials", time: 10) do 54 | render_views 55 | end 56 | -------------------------------------------------------------------------------- /rails/benchmarks/activemodel_views.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'action_controller/railtie' 3 | require 'active_model' 4 | require_relative 'support/benchmark_rails' 5 | 6 | class HeavyController < ActionController::Base 7 | def index;end 8 | end 9 | 10 | class HeavyView < ActionView::Base 11 | def protect_against_forgery? 12 | false 13 | end 14 | end 15 | 16 | class Post 17 | include ActiveModel::Model 18 | 19 | attr_accessor :title, :from, :body 20 | end 21 | 22 | class User 23 | include ActiveModel::Model 24 | 25 | attr_accessor :email 26 | end 27 | 28 | def post_factory 29 | { 30 | title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 31 | from: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 32 | body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit' 33 | } 34 | end 35 | 36 | def user_factory 37 | { 38 | email: 'test@example.com' 39 | } 40 | end 41 | 42 | current_path = File.expand_path File.dirname(__FILE__) 43 | controller = HeavyController.new 44 | controller.request = ActionDispatch::Request.new({}) 45 | 46 | locals = { 47 | posts: (1..50).to_a.map { Post.new(post_factory) }, 48 | users: (1..50).to_a.map { User.new(user_factory) } 49 | } 50 | 51 | view = HeavyView.new("#{current_path}/form_partials", {}, controller) 52 | 53 | Benchmark.rails("actionview_render_activemodels", time: 10) do 54 | view.render(template: "first", layout: "layouts/application", locals: locals) 55 | end 56 | -------------------------------------------------------------------------------- /rails/benchmarks/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | //= require one.js 2 | //= require_tree . 3 | //= link two.js 4 | -------------------------------------------------------------------------------- /rails/benchmarks/assets/javascripts/one.js.erb: -------------------------------------------------------------------------------- 1 | $(function() { 2 | <% 100.times do %> 3 | $(body).append("testing"); 4 | <% end %> 5 | }) 6 | -------------------------------------------------------------------------------- /rails/benchmarks/assets/javascripts/two.js: -------------------------------------------------------------------------------- 1 | alert() 2 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_actioncontroller_api.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'action_controller' 3 | require_relative 'support/benchmark_rails' 4 | 5 | class ApiController < ActionController::API 6 | def show 7 | render json: "JSON", status: :ok 8 | end 9 | end 10 | app = ApiController.action(:show) 11 | request = Rack::MockRequest.new(app) 12 | Benchmark.rails("actioncontroller/api", time: 5) do 13 | response = request.get("/") 14 | fail "Bad response #{response.status}" if response.status != 200 15 | fail "Bad response #{response.body}" if response.body != "JSON" 16 | end 17 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_create_string_columns.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_create_string_columns_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | attributes = {} 13 | 14 | STRING_COLUMNS_COUNT.times do |i| 15 | attributes[:"column#{i}"] = "Some string #{i}" 16 | end 17 | 18 | Benchmark.rails("activerecord/#{db_adapter}_create_string_columns", time: 5) do 19 | User.create!(attributes) 20 | end 21 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_destroy.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_destroy_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | attributes = { 13 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 14 | email: "foobar@email.com" 15 | } 16 | 17 | Benchmark.rails("activerecord/#{db_adapter}_destroy", time: 5) do 18 | # we need to create the record in order to delete it 19 | user = User.create!(attributes) 20 | user.destroy 21 | end 22 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_discourse.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_discourse_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < ActiveRecord::Base 10 | has_many :topic_users 11 | has_many :category_users 12 | has_many :topics 13 | end 14 | 15 | class Topic < ActiveRecord::Base 16 | has_many :topic_users 17 | has_many :categories 18 | belongs_to :user 19 | belongs_to :category 20 | scope :listable_topics, -> { where('topics.archetype <> ?', 'private_message') } 21 | end 22 | 23 | class TopicUser < ActiveRecord::Base 24 | belongs_to :topic 25 | belongs_to :user 26 | end 27 | 28 | class Category < ActiveRecord::Base 29 | has_many :category_users 30 | has_many :topics 31 | belongs_to :topic 32 | end 33 | 34 | class CategoryUser < ActiveRecord::Base 35 | belongs_to :category 36 | belongs_to :user 37 | end 38 | 39 | user = User.first 40 | 41 | Benchmark.rails("active_record/#{db_adapter}_discourse", time: 5) do 42 | str = "" 43 | Topic 44 | .unscoped 45 | .preload(:user) 46 | .includes(:category) 47 | .references(:category) 48 | .joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user.id})") 49 | .listable_topics 50 | .where('COALESCE(categories.topic_id, 0) <> topics.id') 51 | .where('topics.deleted_at IS NULL') 52 | .where( 53 | "NOT EXISTS ( 54 | SELECT 1 FROM category_users cu 55 | WHERE cu.user_id = :user_id 56 | AND cu.category_id = topics.category_id 57 | AND cu.notification_level = :muted 58 | AND cu.category_id <> :category_id 59 | AND (tu.notification_level IS NULL OR tu.notification_level < :tracking) 60 | )", 61 | user_id: user.id, muted: 0, tracking: 2, category_id: -1 62 | ).where("pinned_globally AND pinned_at IS NOT NULL AND (topics.pinned_at > tu.cleared_pinned_at OR tu.cleared_pinned_at IS NULL)") 63 | .order("topics.bumped_at DESC") 64 | .limit(30) 65 | .each do |topic| 66 | str << "id: #{topic.id} title: #{topic.title} created_at: #{topic.created_at.iso8601} user: #{topic.user.username}\n" 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_finders_find_by_attributes.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_finders_find_by_attributes", time: 5) do 13 | user = User.select(:name, :email).find_by(email: 'shatrov@me.com') 14 | str = "name: #{user.name} email: #{user.email}" 15 | end 16 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_finders_find_by_attributes_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_finders_find_by_attributes_over_select", time: 5) do 13 | user = User.find_by(email: 'shatrov@me.com') 14 | str = "name: #{user.name} email: #{user.email}" 15 | end 16 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_finders_find_by_sql.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_find_by_sql", time: 5) do 13 | user = User.find_by("email = :email", email: 'foobar@email.com') 14 | str = "#{user.email} #{user.name}" 15 | end 16 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_finders_first.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_finders_first", time: 5) do 13 | user = User.select(:name, :email).first 14 | str = "name: #{user.name} email: #{user.email}" 15 | end 16 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_finders_first_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_finders_first_over_select", time: 5) do 13 | user = User.first 14 | str = "name: #{user.name} email: #{user.email}" 15 | end 16 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_pluck.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_pluck", time: 5) do 13 | User.all.pluck(:id, :name) 14 | end 15 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_pluck_with_scope.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | last_user_id = User.last.id 13 | 14 | Benchmark.rails("activerecord/#{db_adapter}_pluck_with_scope", time: 5) do 15 | User.where(id: last_user_id).pluck(:name) 16 | end 17 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_preload.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_preload_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class Topic < ActiveRecord::Base 11 | has_many :users 12 | end 13 | 14 | class User < ActiveRecord::Base 15 | belongs_to :topic 16 | end 17 | 18 | Benchmark.rails("activerecord/#{db_adapter}_preload", time: 5) do 19 | User.includes(:topic).all.to_a 20 | end 21 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_save.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_save_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | attributes = { 11 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 12 | email: "foobar@email.com" 13 | } 14 | 15 | class User < ActiveRecord::Base; end 16 | 17 | Benchmark.rails("activerecord/#{db_adapter}_save", time: 5) do 18 | user = User.new(attributes) 19 | 20 | unless user.save 21 | raise "should save correctly" 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_scope_all.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_scope_all_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | 9 | ActiveRecord::Migration.verbose = false 10 | 11 | class User < ActiveRecord::Base; end 12 | 13 | Benchmark.rails("activerecord/#{db_adapter}_scope_all", time: 5) do 14 | str = "" 15 | User.select(:name, :email, :approved, :age, :birthday).each do |user| 16 | str << "name: #{user.name} email: #{user.email} approved: #{user.approved} age: #{user.age} birthday: #{user.birthday}\n" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_scope_all_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_scope_all_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | 9 | ActiveRecord::Migration.verbose = false 10 | 11 | class User < ActiveRecord::Base; end 12 | 13 | Benchmark.rails("activerecord/#{db_adapter}_scope_all_over_select", time: 5) do 14 | str = "" 15 | User.all.each do |user| 16 | str << "name: #{user.name} email: #{user.email} approved: #{user.approved} age: #{user.age} birthday: #{user.birthday}\n" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_scope_all_with_default_scope.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_with_default_scope_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base 11 | default_scope { where(admin: true) } 12 | end 13 | 14 | Benchmark.rails("activerecord/#{db_adapter}_scope_all_with_default_scope", time: 5) do 15 | str = "" 16 | User.select(:name, :email).each do |user| 17 | str << "name: #{user.name} email: #{user.email}\n" 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_scope_all_with_default_scope_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_with_default_scope_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base 11 | default_scope { where(admin: true) } 12 | end 13 | 14 | Benchmark.rails("activerecord/#{db_adapter}_scope_all_with_default_scope_over_select", time: 5) do 15 | str = "" 16 | User.all.each do |user| 17 | str << "name: #{user.name} email: #{user.email}\n" 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_scope_where.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_scope_where_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_scope_where", time: 5) do 13 | str = "" 14 | User 15 | .select(:name, :email) 16 | .where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") 17 | .where("email LIKE :email", email: "foobar00%@email.com") 18 | .each { |user| str << "name: #{user.name} email: #{user.email}\n" } 19 | end 20 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_scope_where_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_scope_where_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class User < ActiveRecord::Base; end 11 | 12 | Benchmark.rails("activerecord/#{db_adapter}_scope_where_over_select", time: 5) do 13 | str = "" 14 | User 15 | .where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") 16 | .where("email LIKE :email", email: "foobar00%@email.com") 17 | .each { |user| str << "name: #{user.name} email: #{user.email}\n" } 18 | end 19 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_validations_invalid.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_validations_invalid_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class Post < ActiveRecord::Base 11 | validates :title, presence: true, confirmation: true 12 | validates :sequence, uniqueness: true 13 | validates :age, numericality: { greater_than: 18, less_than: 80 } 14 | validates :subdomain, exclusion: { in: %w(www us ca jp), 15 | message: "%{value} is reserved." } 16 | validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/, 17 | message: "only allows letters" } 18 | validates :size, inclusion: { in: %w(small medium large), 19 | message: "%{value} is not a valid size" } 20 | end 21 | 22 | post = Post.new({ 23 | title: '', 24 | author: '', 25 | age: 10, 26 | sequence: 90, 27 | subdomain: 'jp', 28 | legacy_code: '32_leg', 29 | size: 'overbig' 30 | }) 31 | 32 | Benchmark.rails("activerecord/#{db_adapter}_validations_invalid", time: 5) do 33 | if post.valid? 34 | raise "should not be valid" 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_activerecord_validations_valid.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'active_record' 3 | require_relative 'support/benchmark_rails' 4 | 5 | db_setup script: "bm_validations_valid_setup.rb" 6 | 7 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 8 | ActiveRecord::Migration.verbose = false 9 | 10 | class Post < ActiveRecord::Base 11 | validates :title, presence: true, confirmation: true 12 | validates :sequence, uniqueness: true 13 | validates :age, numericality: { greater_than: 18, less_than: 80 } 14 | validates :subdomain, exclusion: { in: %w(www us ca jp), 15 | message: "%{value} is reserved." } 16 | validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/, 17 | message: "only allows letters" } 18 | validates :size, inclusion: { in: %w(small medium large), 19 | message: "%{value} is not a valid size" } 20 | end 21 | 22 | post = Post.new({ 23 | title: 'RubyBench', 24 | author: 'RubyBench', 25 | age: 21, 26 | sequence: 50, 27 | subdomain: 'ru', 28 | legacy_code: 'letters', 29 | size: 'small' 30 | }) 31 | 32 | Benchmark.rails("activerecord/#{db_adapter}_validations_valid", time: 5) do 33 | unless post.valid? 34 | raise "should be valid" 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_scaffold_create.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'rails' 3 | require 'action_controller/railtie' 4 | require 'active_record' 5 | require_relative 'support/benchmark_rails' 6 | require_relative 'support/request_helper' 7 | 8 | class ScaffoldApp < Rails::Application 9 | config.secret_token = "s"*30 10 | config.secret_key_base = 'foo' 11 | config.cache_classes = true 12 | config.eager_load = true 13 | config.consider_all_requests_local = false 14 | config.action_controller.perform_caching = true 15 | config.log_level = :debug 16 | config.active_support.deprecation = :notify 17 | config.log_formatter = ::Logger::Formatter.new 18 | # otherwise deadlock occurs 19 | config.middleware.delete "Rack::Lock" 20 | end 21 | 22 | ScaffoldApp.initialize! 23 | 24 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 25 | ActiveRecord::Migration.verbose = false 26 | 27 | ActiveRecord::Schema.define do 28 | create_table :posts, force: true do |t| 29 | t.string :title 30 | t.string :author 31 | t.text :body 32 | t.timestamps 33 | end 34 | end 35 | 36 | Rails.application.routes.draw do 37 | resources :posts 38 | end 39 | 40 | class Post < ActiveRecord::Base; end 41 | 42 | ActionController::Base.prepend_view_path File.expand_path("../views", __FILE__) 43 | 44 | class PostsController < ActionController::Base 45 | # POST /posts 46 | # POST /posts.json 47 | def create 48 | @post = Post.new(post_params) 49 | 50 | respond_to do |format| 51 | if @post.save 52 | format.html { redirect_to @post, notice: 'Post was successfully created.' } 53 | format.json { render :show, status: :created, location: @post } 54 | else 55 | format.html { render :new } 56 | format.json { render json: @post.errors, status: :unprocessable_entity } 57 | end 58 | end 59 | end 60 | 61 | private 62 | 63 | # Never trust parameters from the scary internet, only allow the white list through. 64 | def post_params 65 | params.require(:post).permit(:id, :title, :body, :author) 66 | end 67 | end 68 | 69 | request = Rack::MockRequest.env_for( 70 | "http://localhost:3000/posts", 71 | method: 'POST', 72 | input: "post%5Bauthor%5D=C&post%5Bbody%5D=B&post%5Btitle%5D=A", 73 | ).merge("CONTENT_TYPE" => "application/x-www-form-urlencoded") 74 | 75 | Benchmark.rails("request/#{db_adapter}_scaffold_create", time: 5) { RequestHelper.perform(ScaffoldApp, request) } 76 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_scaffold_index.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'rails' 3 | require 'action_controller/railtie' 4 | require 'active_record' 5 | require_relative 'support/benchmark_rails' 6 | require_relative 'support/request_helper' 7 | 8 | class ScaffoldApp < Rails::Application 9 | config.secret_token = "s"*30 10 | config.secret_key_base = 'foo' 11 | config.cache_classes = true 12 | config.eager_load = true 13 | config.consider_all_requests_local = false 14 | config.action_controller.perform_caching = true 15 | config.log_level = :debug 16 | config.active_support.deprecation = :notify 17 | config.log_formatter = ::Logger::Formatter.new 18 | # otherwise deadlock occurs 19 | config.middleware.delete "Rack::Lock" 20 | end 21 | 22 | ScaffoldApp.initialize! 23 | 24 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 25 | ActiveRecord::Migration.verbose = false 26 | 27 | ActiveRecord::Schema.define do 28 | create_table :posts, force: true do |t| 29 | t.string :title 30 | t.string :author 31 | t.text :body 32 | t.timestamps 33 | end 34 | end 35 | 36 | Rails.application.routes.draw do 37 | resources :posts 38 | end 39 | 40 | class Post < ActiveRecord::Base; end 41 | 42 | ActionController::Base.prepend_view_path File.expand_path("../views", __FILE__) 43 | 44 | class PostsController < ActionController::Base 45 | # GET /posts 46 | # GET /posts.json 47 | def index 48 | @posts = Post.all 49 | end 50 | end 51 | 52 | 100.times do 53 | Post.create!( 54 | title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 55 | body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 56 | author: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit' 57 | ) 58 | end 59 | 60 | request = Rack::MockRequest.env_for( 61 | "http://localhost:3000/posts", 62 | method: 'GET', 63 | ) 64 | 65 | Benchmark.rails("request/#{db_adapter}_scaffold_index", time: 5) { RequestHelper.perform(ScaffoldApp, request) } 66 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_scaffold_new.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'rails' 3 | require 'action_controller/railtie' 4 | require 'active_record' 5 | require_relative 'support/benchmark_rails' 6 | require_relative 'support/request_helper' 7 | 8 | class ScaffoldApp < Rails::Application 9 | config.secret_token = "s"*30 10 | config.secret_key_base = 'foo' 11 | config.cache_classes = true 12 | config.eager_load = true 13 | config.consider_all_requests_local = false 14 | config.action_controller.perform_caching = true 15 | config.log_level = :debug 16 | config.active_support.deprecation = :notify 17 | config.log_formatter = ::Logger::Formatter.new 18 | # otherwise deadlock occurs 19 | config.middleware.delete "Rack::Lock" 20 | end 21 | 22 | ScaffoldApp.initialize! 23 | 24 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 25 | ActiveRecord::Migration.verbose = false 26 | 27 | ActiveRecord::Schema.define do 28 | create_table :posts, force: true do |t| 29 | t.string :title 30 | t.string :author 31 | t.text :body 32 | t.timestamps 33 | end 34 | end 35 | 36 | Rails.application.routes.draw do 37 | resources :posts 38 | end 39 | 40 | class Post < ActiveRecord::Base; end 41 | 42 | ActionController::Base.prepend_view_path File.expand_path("../views", __FILE__) 43 | 44 | class PostsController < ActionController::Base 45 | # GET /posts/new 46 | def new 47 | @post = Post.new 48 | end 49 | end 50 | 51 | request = Rack::MockRequest.env_for( 52 | "http://localhost:3000/posts/new", 53 | method: 'GET', 54 | ) 55 | 56 | Benchmark.rails("request/#{db_adapter}_scaffold_new", time: 5) { RequestHelper.perform(ScaffoldApp, request) } 57 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_scaffold_show.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'rails' 3 | require 'action_controller/railtie' 4 | require 'active_record' 5 | require_relative 'support/benchmark_rails' 6 | require_relative 'support/request_helper' 7 | 8 | class ScaffoldApp < Rails::Application 9 | config.secret_token = "s"*30 10 | config.secret_key_base = 'foo' 11 | config.cache_classes = true 12 | config.eager_load = true 13 | config.consider_all_requests_local = false 14 | config.action_controller.perform_caching = true 15 | config.log_level = :debug 16 | config.active_support.deprecation = :notify 17 | config.log_formatter = ::Logger::Formatter.new 18 | # otherwise deadlock occurs 19 | config.middleware.delete "Rack::Lock" 20 | end 21 | 22 | ScaffoldApp.initialize! 23 | 24 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 25 | ActiveRecord::Migration.verbose = false 26 | 27 | ActiveRecord::Schema.define do 28 | create_table :posts, force: true do |t| 29 | t.string :title 30 | t.string :author 31 | t.text :body 32 | t.timestamps 33 | end 34 | end 35 | 36 | Rails.application.routes.draw do 37 | resources :posts 38 | end 39 | 40 | class Post < ActiveRecord::Base; end 41 | 42 | ActionController::Base.prepend_view_path File.expand_path("../views", __FILE__) 43 | 44 | class PostsController < ActionController::Base 45 | if Rails.version > '2.3.8' 46 | before_action :set_post, only: [:show] 47 | else 48 | before_filter :set_post, only: [:show] 49 | end 50 | 51 | # GET /posts/1 52 | # GET /posts/1.json 53 | def show 54 | end 55 | 56 | private 57 | 58 | # Use callbacks to share common setup or constraints between actions. 59 | def set_post 60 | @post = Post.find(params[:id]) 61 | end 62 | end 63 | 64 | Post.create!( 65 | id: 1, 66 | title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 67 | body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 68 | author: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit' 69 | ) 70 | 71 | request = Rack::MockRequest.env_for( 72 | "http://localhost:3000/posts/1", 73 | method: 'GET', 74 | ) 75 | 76 | Benchmark.rails("request/#{db_adapter}_scaffold_show", time: 5) { RequestHelper.perform(ScaffoldApp, request) } 77 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_scaffold_update.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'rails' 3 | require 'action_controller/railtie' 4 | require 'active_record' 5 | require_relative 'support/benchmark_rails' 6 | require_relative 'support/request_helper' 7 | 8 | class ScaffoldApp < Rails::Application 9 | config.secret_token = "s"*30 10 | config.secret_key_base = 'foo' 11 | config.cache_classes = true 12 | config.eager_load = true 13 | config.consider_all_requests_local = false 14 | config.action_controller.perform_caching = true 15 | config.log_level = :debug 16 | config.active_support.deprecation = :notify 17 | config.log_formatter = ::Logger::Formatter.new 18 | # otherwise deadlock occurs 19 | config.middleware.delete "Rack::Lock" 20 | end 21 | 22 | ScaffoldApp.initialize! 23 | 24 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 25 | ActiveRecord::Migration.verbose = false 26 | 27 | ActiveRecord::Schema.define do 28 | create_table :posts, force: true do |t| 29 | t.string :title 30 | t.string :author 31 | t.text :body 32 | t.timestamps 33 | end 34 | end 35 | 36 | Rails.application.routes.draw do 37 | resources :posts 38 | end 39 | 40 | class Post < ActiveRecord::Base; end 41 | 42 | ActionController::Base.prepend_view_path File.expand_path("../views", __FILE__) 43 | 44 | class PostsController < ActionController::Base 45 | if Rails.version > '2.3.8' 46 | before_action :set_post, only: [:update] 47 | else 48 | before_filter :set_post, only: [:update] 49 | end 50 | 51 | # GET /posts/1/edit 52 | def edit 53 | end 54 | 55 | # PATCH/PUT /posts/1 56 | # PATCH/PUT /posts/1.json 57 | def update 58 | respond_to do |format| 59 | if @post.update_attributes(post_params) 60 | format.html { redirect_to @post, notice: 'Post was successfully updated.' } 61 | format.json { render :show, status: :ok, location: @post } 62 | else 63 | format.html { render :edit } 64 | format.json { render json: @post.errors, status: :unprocessable_entity } 65 | end 66 | end 67 | end 68 | 69 | private 70 | 71 | # Use callbacks to share common setup or constraints between actions. 72 | def set_post 73 | @post = Post.find(params[:id]) 74 | end 75 | 76 | # Never trust parameters from the scary internet, only allow the white list through. 77 | def post_params 78 | params.require(:post).permit(:id, :title, :body, :author) 79 | end 80 | end 81 | 82 | Post.create!( 83 | id: 1, 84 | title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 85 | body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 86 | author: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit' 87 | ) 88 | 89 | request = Rack::MockRequest.env_for( 90 | "http://localhost:3000/posts/1", 91 | method: 'PUT', 92 | input: "post%5Bauthor%5D=C&post%5Bbody%5D=B&post%5Btitle%5D=A", 93 | ).merge("CONTENT_TYPE" => "application/x-www-form-urlencoded") 94 | 95 | Benchmark.rails("request/#{db_adapter}_scaffold_update", time: 5) { RequestHelper.perform(ScaffoldApp, request) } 96 | -------------------------------------------------------------------------------- /rails/benchmarks/bm_sprockets_javascript.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sprockets' 3 | require_relative 'support/benchmark_rails' 4 | require 'rack/builder' 5 | 6 | app = Rack::Builder.new do 7 | map "/assets" do 8 | environment = Sprockets::Environment.new 9 | environment.append_path File.expand_path('../assets/javascripts', __FILE__) 10 | run environment 11 | end 12 | end 13 | request = Rack::MockRequest.env_for("/assets/application.js") 14 | 15 | Benchmark.rails("sprockets/simple", time: 3.seconds) do 16 | response = app.call(request) 17 | raise "request is broken" unless response[0] == 200 18 | end 19 | -------------------------------------------------------------------------------- /rails/benchmarks/form_partials/first.html.erb: -------------------------------------------------------------------------------- 1 | <%= content_for(:title, "my title") %> 2 | <%= content_for(:meta) { "embedded content" * 20 } %> 3 | <% 3.times do |record| %> 4 | <%= record %> 5 |

6 | London is the capital city of England. It is the most populous city in the United Kingdom, 7 | with a metropolitan area of over 13 million inhabitants. 8 |

9 |

10 | Standing on the River Thames, London has been a major settlement for two millennia, 11 | its history going back to its founding by the Romans, who named it Londinium. 12 |

13 | 14 | <%= render partial: 'third', locals: { users: users } %> 15 | <% end %> 16 | 17 | <%= render collection: posts, partial: 'item', as: :post %> 18 | -------------------------------------------------------------------------------- /rails/benchmarks/form_partials/heavy/_item.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for post, url: '/posts' do |f|%> 2 | <%= f.label :body %> 3 | <%= f.text_field :body %> 4 | 5 | <%= f.label :from %> 6 | <%= f.text_field :from %> 7 | 8 | <%= f.label :title %> 9 | <%= f.text_field :title %> 10 | 11 | <%= f.submit 'save' %> 12 | <% end %> 13 | -------------------------------------------------------------------------------- /rails/benchmarks/form_partials/heavy/_second.html.erb: -------------------------------------------------------------------------------- 1 | <% posts.each do |post| %> 2 |

<%= post.title %>

3 |

<%= post.body %>

4 | <%= post.from %> 5 | 6 | <%= render partial: 'third', locals: { users: users } %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /rails/benchmarks/form_partials/heavy/_third.html.erb: -------------------------------------------------------------------------------- 1 | <% users.each do |user| %> 2 | <%= form_for user, url: '/users' do |f|%> 3 | <%= f.label :email %> 4 | <%= f.email_field :email %> 5 | 6 | <%= f.submit 'save' %> 7 | <% end %> 8 | <% end %> 9 | -------------------------------------------------------------------------------- /rails/benchmarks/form_partials/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= yield(:title) %> 4 | <%= yield(:meta) %> 5 | 6 | 7 | 8 | 11 | 12 | 17 | 18 |
19 |

London

20 | <%= yield %> 21 |
22 | 23 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /rails/benchmarks/partials/first.html.erb: -------------------------------------------------------------------------------- 1 | <%= content_for(:title, "my title") %> 2 | <%= content_for(:meta) { "embedded content" * 20 } %> 3 | <% records.times do |record| %> 4 | <%= record %> 5 |

6 | London is the capital city of England. It is the most populous city in the United Kingdom, 7 | with a metropolitan area of over 13 million inhabitants. 8 |

9 |

10 | Standing on the River Thames, London has been a major settlement for two millennia, 11 | its history going back to its founding by the Romans, who named it Londinium. 12 |

13 | 14 | <%= render partial: 'second', locals: { posts: posts, users: users } %> 15 | <% end %> 16 | 17 | <%= render collections: posts, partial: 'item' %> 18 | 19 | <%= debug @more_records %> 20 | -------------------------------------------------------------------------------- /rails/benchmarks/partials/heavy/_item.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruby-bench/ruby-bench-suite/049ed0e898a4dfb06945ac63fb56457c094eeffa/rails/benchmarks/partials/heavy/_item.html.erb -------------------------------------------------------------------------------- /rails/benchmarks/partials/heavy/_second.html.erb: -------------------------------------------------------------------------------- 1 | <% posts.each do |post| %> 2 |

<%= post.title %>

3 |

<%= post.body %>

4 | <%= post.from %> 5 | 6 | <%= render partial: 'third', locals: { users: users } %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /rails/benchmarks/partials/heavy/_third.html.erb: -------------------------------------------------------------------------------- 1 | <% users.each do |user| %> 2 | <%= user.email %> 3 | <% end %> 4 | -------------------------------------------------------------------------------- /rails/benchmarks/partials/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= yield(:title) %> 4 | <%= yield(:meta) %> 5 | 6 | 7 | 8 | 11 | 12 | 17 | 18 |
19 |

London

20 | <%= yield %> 21 |
22 | 23 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /rails/benchmarks/support/benchmark_rails.rb: -------------------------------------------------------------------------------- 1 | require 'rails' 2 | 3 | require_relative '../../../support/benchmark_runner' 4 | require_relative '../../../support/helpers' 5 | 6 | module Benchmark 7 | module Rails 8 | def rails(label = nil, version: ::Rails.version.to_s, time:, disable_gc: true, warmup: 3, &block) 9 | Benchmark::Runner.run(label, version: version, time: time, disable_gc: disable_gc, warmup: warmup, &block) 10 | end 11 | end 12 | 13 | extend Benchmark::Rails 14 | end 15 | -------------------------------------------------------------------------------- /rails/benchmarks/support/echo_channel.rb: -------------------------------------------------------------------------------- 1 | class EchoChannel < ApplicationCable::Channel 2 | def subscribed 3 | stream_from "echo_channel" 4 | end 5 | 6 | def unsubscribed 7 | # Any cleanup needed when channel is unsubscribed 8 | end 9 | 10 | def ding(data) 11 | transmit(dong: data['message']) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /rails/benchmarks/support/request_helper.rb: -------------------------------------------------------------------------------- 1 | module RequestHelper 2 | VALID_STATUS = [200, 302] 3 | 4 | def self.perform(app, request) 5 | status, _, body = app.call(request) 6 | raise "Error: response status: #{status}" unless VALID_STATUS.include?(status) 7 | body.close if body.respond_to?(:close) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /rails/benchmarks/support/url_generation_base.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | 3 | require 'rails' 4 | require 'action_controller/railtie' 5 | 6 | class NullLogger < Logger 7 | def initialize(*args) 8 | end 9 | 10 | def add(*args, &block) 11 | end 12 | end 13 | 14 | class BenchmarkApp < Rails::Application 15 | routes.append do 16 | namespace :editor do 17 | resources :professionals 18 | resource :message 19 | end 20 | 21 | scope path: '/prices' do 22 | get 'info' => 'prices#info' 23 | end 24 | 25 | scope '/coupon' do 26 | get 'some' => 'coupons#some' 27 | end 28 | 29 | root to: "home#index" 30 | 31 | resources :topics do 32 | resources :messages do 33 | resources :likes 34 | end 35 | end 36 | 37 | resources :professionals, only: [:index] do 38 | collection do 39 | match 'category/:specialization_id', to: 'professionals#by_category', as: :by_category, via: [:get, :post] 40 | end 41 | end 42 | 43 | get "/listings/:any" => redirect("/properties/%{any}"), as: :listing_redirect 44 | 45 | constraints id: /\d+(.*)/ do 46 | get '/residential/*addressing_slug/:id', 47 | to: 'residential_listings#show', 48 | as: :residential 49 | end 50 | end 51 | 52 | config.secret_token = "s"*30 53 | config.secret_key_base = 'foo' 54 | config.consider_all_requests_local = false 55 | 56 | # simulate production 57 | config.cache_classes = true 58 | config.eager_load = true 59 | config.action_controller.perform_caching = true 60 | 61 | # otherwise deadlock occured 62 | config.middleware.delete "Rack::Lock" 63 | 64 | # to disable log files 65 | config.logger = NullLogger.new 66 | config.active_support.deprecation = :log 67 | end 68 | 69 | BenchmarkApp.initialize! 70 | 71 | class Router 72 | include BenchmarkApp.routes.url_helpers 73 | 74 | def default_url_options 75 | { 76 | host: 'railsperf.io' 77 | } 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@post) do |f| %> 2 | <% if @post.errors.any? %> 3 |
4 |

<%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:

5 | 6 | 11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :title %>
16 | <%= f.text_field :title %> 17 |
18 |
19 | <%= f.label :body %>
20 | <%= f.text_field :body %> 21 |
22 |
23 | <%= f.label :author %>
24 | <%= f.text_field :author %> 25 |
26 |
27 | <%= f.submit %> 28 |
29 | <% end %> 30 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Post

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Show', @post %> | 6 | <%= link_to 'Back', posts_path %> 7 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/index.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

Listing Posts

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <%= posts_path %> 17 | <% @posts.each do |post| %> 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | <% end %> 27 | 28 |
TitleBodyAuthor
<%= post.title %><%= post.body %><%= post.author %><%= link_to 'Show', post %><%= link_to 'Edit', edit_post_path(post) %><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>
29 | 30 |
31 | 32 | <%= link_to 'New Post', new_post_path %> 33 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@posts) do |post| 2 | json.extract! post, :id, :title, :body, :author 3 | json.url post_url(post, format: :json) 4 | end 5 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Post

2 | 3 | <%= render 'form' %> 4 | 5 | <%= link_to 'Back', posts_path %> 6 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Title: 5 | <%= @post.title %> 6 |

7 | 8 |

9 | Body: 10 | <%= @post.body %> 11 |

12 | 13 |

14 | Author: 15 | <%= @post.author %> 16 |

17 | 18 | <%= link_to 'Edit', edit_post_path(@post) %> | 19 | <%= link_to 'Back', posts_path %> 20 | -------------------------------------------------------------------------------- /rails/benchmarks/views/posts/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @post, :id, :title, :body, :author, :created_at, :updated_at 2 | -------------------------------------------------------------------------------- /ruby/benchmark/app_answer.rb: -------------------------------------------------------------------------------- 1 | def ack(m, n) 2 | if m == 0 then 3 | n + 1 4 | elsif n == 0 then 5 | ack(m - 1, 1) 6 | else 7 | ack(m - 1, ack(m, n - 1)) 8 | end 9 | end 10 | 11 | def the_answer_to_life_the_universe_and_everything 12 | (ack(3,7).to_s.split(//).inject(0){|s,x| s+x.to_i}.to_s + "2" ).to_i 13 | end 14 | 15 | answer = the_answer_to_life_the_universe_and_everything 16 | -------------------------------------------------------------------------------- /ruby/benchmark/app_erb.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Create many HTML strings with ERB. 3 | # 4 | prelude: | 5 | require 'erb' 6 | 7 | data = < 9 | <%= title %> 10 | 11 |

<%= title %>

12 |

13 | <%= content %> 14 |

15 | 16 | 17 | erb 18 | 19 | max = 15_000 20 | title = "hello world!" 21 | content = "hello world!\n" * 10 22 | benchmark: 23 | app_erb: ERB.new(data).result(binding) 24 | loop_count: 15000 25 | -------------------------------------------------------------------------------- /ruby/benchmark/app_factorial.rb: -------------------------------------------------------------------------------- 1 | def fact(n) 2 | if(n > 1) 3 | n * fact(n-1) 4 | else 5 | 1 6 | end 7 | end 8 | 9 | 100.times { 10 | fact(5000) 11 | } 12 | -------------------------------------------------------------------------------- /ruby/benchmark/app_fib.rb: -------------------------------------------------------------------------------- 1 | def fib n 2 | if n < 3 3 | 1 4 | else 5 | fib(n-1) + fib(n-2) 6 | end 7 | end 8 | 9 | fib(34) 10 | 11 | -------------------------------------------------------------------------------- /ruby/benchmark/app_mandelbrot.rb: -------------------------------------------------------------------------------- 1 | require 'complex' 2 | 3 | def mandelbrot? z 4 | i = 0 5 | while i<100 6 | i += 1 7 | z = z * z 8 | return false if z.abs > 2 9 | end 10 | true 11 | end 12 | 13 | ary = [] 14 | 15 | (0..1000).each{|dx| 16 | (0..1000).each{|dy| 17 | x = dx / 50.0 18 | y = dy / 50.0 19 | c = Complex(x, y) 20 | ary << c if mandelbrot?(c) 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /ruby/benchmark/app_pentomino.rb: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/ruby 2 | # This program is contributed by Shin Nishiyama 3 | 4 | 5 | # modified by K.Sasada 6 | 7 | NP = 5 8 | ROW = 8 + NP 9 | COL = 8 10 | 11 | $p = [] 12 | $b = [] 13 | $no = 0 14 | 15 | def piece(n, a, nb) 16 | nb.each{|x| 17 | a[n] = x 18 | if n == NP-1 19 | $p << [a.sort] 20 | else 21 | nbc=nb.dup 22 | [-ROW, -1, 1, ROW].each{|d| 23 | if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d) 24 | nbc << x+d 25 | end 26 | } 27 | nbc.delete x 28 | piece(n+1,a[0..n],nbc) 29 | end 30 | } 31 | end 32 | 33 | def kikaku(a) 34 | a.collect {|x| x - a[0]} 35 | end 36 | def ud(a) 37 | kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort) 38 | end 39 | def rl(a) 40 | kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort) 41 | end 42 | def xy(a) 43 | kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort) 44 | end 45 | 46 | def mkpieces 47 | piece(0,[],[0]) 48 | $p.each do |a| 49 | a0 = a[0] 50 | a[1] = ud(a0) 51 | a[2] = rl(a0) 52 | a[3] = ud(rl(a0)) 53 | a[4] = xy(a0) 54 | a[5] = ud(xy(a0)) 55 | a[6] = rl(xy(a0)) 56 | a[7] = ud(rl(xy(a0))) 57 | a.sort! 58 | a.uniq! 59 | end 60 | $p.uniq!.sort! {|x,y| x[0] <=> y[0] } 61 | end 62 | 63 | def mkboard 64 | (0...ROW*COL).each{|i| 65 | if i % ROW >= ROW-NP 66 | $b[i] = -2 67 | else 68 | $b[i] = -1 69 | end 70 | $b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2 71 | } 72 | end 73 | 74 | def pboard 75 | return # skip print 76 | print "No. #$no\n" 77 | (0...COL).each{|i| 78 | print "|" 79 | (0...ROW-NP).each{|j| 80 | x = $b[i*ROW+j] 81 | if x < 0 82 | print "..|" 83 | else 84 | printf "%2d|",x+1 85 | end 86 | } 87 | print "\n" 88 | } 89 | print "\n" 90 | end 91 | 92 | $pnum=[] 93 | def setpiece(a,pos) 94 | if a.length == $p.length then 95 | $no += 1 96 | pboard 97 | return 98 | end 99 | while $b[pos] != -1 100 | pos += 1 101 | end 102 | ($pnum - a).each do |i| 103 | $p[i].each do |x| 104 | f = 0 105 | x.each{|s| 106 | if $b[pos+s] != -1 107 | f=1 108 | break 109 | end 110 | } 111 | if f == 0 then 112 | x.each{|s| 113 | $b[pos+s] = i 114 | } 115 | a << i 116 | setpiece(a.dup, pos) 117 | a.pop 118 | x.each{|s| 119 | $b[pos+s] = -1 120 | } 121 | end 122 | end 123 | end 124 | end 125 | 126 | mkpieces 127 | mkboard 128 | $p[4] = [$p[4][0]] 129 | $pnum = (0...$p.length).to_a 130 | setpiece([],0) 131 | -------------------------------------------------------------------------------- /ruby/benchmark/app_raise.rb: -------------------------------------------------------------------------------- 1 | i = 0 2 | while i<300000 3 | i += 1 4 | begin 5 | raise 6 | rescue 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /ruby/benchmark/app_strconcat.rb: -------------------------------------------------------------------------------- 1 | i = 0 2 | while i<2_000_000 3 | "#{1+1} #{1+1} #{1+1}" 4 | i += 1 5 | end 6 | -------------------------------------------------------------------------------- /ruby/benchmark/app_tak.rb: -------------------------------------------------------------------------------- 1 | 2 | def tak x, y, z 3 | unless y < x 4 | z 5 | else 6 | tak( tak(x-1, y, z), 7 | tak(y-1, z, x), 8 | tak(z-1, x, y)) 9 | end 10 | end 11 | 12 | tak(18, 9, 0) 13 | 14 | -------------------------------------------------------------------------------- /ruby/benchmark/app_tarai.rb: -------------------------------------------------------------------------------- 1 | def tarai( x, y, z ) 2 | if x <= y 3 | then y 4 | else tarai(tarai(x-1, y, z), 5 | tarai(y-1, z, x), 6 | tarai(z-1, x, y)) 7 | end 8 | end 9 | 10 | tarai(12, 6, 0) 11 | -------------------------------------------------------------------------------- /ruby/benchmark/app_uri.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | 3 | 100_000.times{ 4 | uri = URI.parse('http://www.ruby-lang.org') 5 | uri.scheme 6 | uri.host 7 | uri.port 8 | } 9 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k_10.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 10} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k_11.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 11} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k__100.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 100} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k__1k.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 1000} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k__6k.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 6000} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k___10k.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 10_000} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sample_100k___50k.rb: -------------------------------------------------------------------------------- 1 | arr = [*0...100000] 2 | 10_000.times {arr.sample 50_000} 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_shift.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | 3 | Benchmark.bm do |x| 4 | [10_000,1_000_000,100_000_000].each do |n| 5 | ary = Array.new(n,0) 6 | GC.start 7 | x.report("#{n}:shift"){ ary.shift } 8 | (0..4).each do |i| 9 | ary = Array.new(n,0) 10 | GC.start 11 | x.report("#{n}:shift(#{i})"){ ary.shift(i) } 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /ruby/benchmark/array_small_and.rb: -------------------------------------------------------------------------------- 1 | MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i 2 | MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i 3 | ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i 4 | 5 | ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1| 6 | (MIN_SIZE..MAX_SIZE).map do |size2| 7 | [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }] 8 | end 9 | end 10 | 11 | ITERATIONS.times do 12 | ARRAYS.each do |group| 13 | group.each do |arr1, arr2| 14 | arr1 & arr2 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /ruby/benchmark/array_small_diff.rb: -------------------------------------------------------------------------------- 1 | MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i 2 | MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i 3 | ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i 4 | 5 | ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1| 6 | (MIN_SIZE..MAX_SIZE).map do |size2| 7 | [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }] 8 | end 9 | end 10 | 11 | ITERATIONS.times do 12 | ARRAYS.each do |group| 13 | group.each do |arr1, arr2| 14 | arr1 - arr2 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /ruby/benchmark/array_small_or.rb: -------------------------------------------------------------------------------- 1 | MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i 2 | MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i 3 | ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i 4 | 5 | ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1| 6 | (MIN_SIZE..MAX_SIZE).map do |size2| 7 | [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }] 8 | end 9 | end 10 | 11 | ITERATIONS.times do 12 | ARRAYS.each do |group| 13 | group.each do |arr1, arr2| 14 | arr1 | arr2 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sort_block.rb: -------------------------------------------------------------------------------- 1 | ary = Array.new(1000) { rand(1000) } 2 | 10000.times { ary.sort { |a, b| a <=> b } } 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_sort_float.rb: -------------------------------------------------------------------------------- 1 | arr = Array.new(1000) { rand } 2 | 10000.times { arr.sort } 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_values_at_int.rb: -------------------------------------------------------------------------------- 1 | ary = Array.new(10000) {|i| i} 2 | 100000.times { ary.values_at(500) } 3 | -------------------------------------------------------------------------------- /ruby/benchmark/array_values_at_range.rb: -------------------------------------------------------------------------------- 1 | ary = Array.new(10000) {|i| i} 2 | 100000.times { ary.values_at(1..2000) } 3 | -------------------------------------------------------------------------------- /ruby/benchmark/bighash.rb: -------------------------------------------------------------------------------- 1 | h = {}; 5000000.times {|n| h[n] = n } 2 | -------------------------------------------------------------------------------- /ruby/benchmark/cgi_escape_html.yml: -------------------------------------------------------------------------------- 1 | prelude: require 'cgi/escape' 2 | benchmark: 3 | - name: escape_html_blank 4 | prelude: str = "" 5 | script: CGI.escapeHTML(str) 6 | loop_count: 20000000 7 | - name: escape_html_short_none 8 | prelude: str = "abcde" 9 | script: CGI.escapeHTML(str) 10 | loop_count: 20000000 11 | - name: escape_html_short_one 12 | prelude: str = "abcd<" 13 | script: CGI.escapeHTML(str) 14 | loop_count: 20000000 15 | - name: escape_html_short_all 16 | prelude: str = "'&\"<>" 17 | script: CGI.escapeHTML(str) 18 | loop_count: 5000000 19 | - name: escape_html_long_none 20 | prelude: str = "abcde" * 300 21 | script: CGI.escapeHTML(str) 22 | loop_count: 1000000 23 | - name: escape_html_long_all 24 | prelude: str = "'&\"<>" * 10 25 | script: CGI.escapeHTML(str) 26 | loop_count: 1000000 27 | - name: escape_html_real 28 | prelude: | # http://example.com/ 29 | str = <<~HTML 30 | 31 |
32 |

Example Domain

33 |

This domain is established to be used for illustrative examples in documents. You may use this 34 | domain in examples without prior coordination or asking for permission.

35 |

More information...

36 |
37 | 38 | HTML 39 | script: CGI.escapeHTML(str) 40 | loop_count: 1000000 41 | -------------------------------------------------------------------------------- /ruby/benchmark/complex_float_add.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | max, min = 1000.0, -1000.0 3 | a = Complex(rand(max)+min, rand(max)+min) 4 | b = Complex(rand(max)+min, rand(max)+min) 5 | benchmark: 6 | complex_float_add: c = a + b 7 | loop_count: 1000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/complex_float_div.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | max, min = 1000.0, -1000.0 3 | a = Complex(rand(max)+min, rand(max)+min) 4 | b = Complex(rand(max)+min, rand(max)+min) 5 | benchmark: 6 | complex_float_div: c = a / b 7 | loop_count: 1000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/complex_float_mul.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | max, min = 1000.0, -1000.0 3 | a = Complex(rand(max)+min, rand(max)+min) 4 | b = Complex(rand(max)+min, rand(max)+min) 5 | benchmark: 6 | complex_float_mul: c = a * b 7 | loop_count: 1000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/complex_float_new.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | max, min = 1000.0, -1000.0 3 | a = Complex(rand(max)+min, rand(max)+min) 4 | b = Complex(rand(max)+min, rand(max)+min) 5 | benchmark: 6 | complex_float_new: c = Complex(a, b) 7 | loop_count: 1000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/complex_float_power.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | max, min = 1000.0, -1000.0 3 | a = Complex(rand(max)+min, rand(max)+min) 4 | b = Complex(rand(max)+min, rand(max)+min) 5 | benchmark: 6 | complex_float_power: c = a ** b 7 | loop_count: 1000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/complex_float_sub.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | max, min = 1000.0, -1000.0 3 | a = Complex(rand(max)+min, rand(max)+min) 4 | b = Complex(rand(max)+min, rand(max)+min) 5 | benchmark: 6 | complex_float_sub: c = a - b 7 | loop_count: 1000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/dir_empty_p.rb: -------------------------------------------------------------------------------- 1 | require 'tmpdir' 2 | max = 100_000 3 | Dir.mktmpdir('bm_dir_empty_p') do |dir| 4 | max.times { Dir.empty?(dir) } 5 | end 6 | -------------------------------------------------------------------------------- /ruby/benchmark/enum_lazy_grep_v_100.rb: -------------------------------------------------------------------------------- 1 | grep_data = (1..10).to_a * 1000 2 | N = 100 3 | enum = grep_data.lazy.grep_v(->(i){i == 0}).grep_v(->(i){i == 0}) 4 | N.times {enum.each {}} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/enum_lazy_grep_v_20.rb: -------------------------------------------------------------------------------- 1 | grep_data = (1..10).to_a * 1000 2 | N = 100 3 | enum = grep_data.lazy.grep_v(->(i){i > 2}).grep_v(->(i){i > 2}) 4 | N.times {enum.each {}} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/enum_lazy_grep_v_50.rb: -------------------------------------------------------------------------------- 1 | grep_data = (1..10).to_a * 1000 2 | N = 100 3 | enum = grep_data.lazy.grep_v(->(i){i > 5}).grep_v(->(i){i > 5}) 4 | N.times {enum.each {}} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/enum_lazy_uniq_100.rb: -------------------------------------------------------------------------------- 1 | uniq_data = (1..10_000).to_a 2 | N = 100 3 | enum = uniq_data.lazy.uniq {|i| i % 10000}.uniq {|i| i % 10000} 4 | N.times {enum.each {}} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/enum_lazy_uniq_20.rb: -------------------------------------------------------------------------------- 1 | uniq_data = (1..10_000).to_a 2 | N = 100 3 | enum = uniq_data.lazy.uniq {|i| i % 2000}.uniq {|i| i % 2000} 4 | N.times {enum.each {}} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/enum_lazy_uniq_50.rb: -------------------------------------------------------------------------------- 1 | uniq_data = (1..10_000).to_a 2 | N = 100 3 | enum = uniq_data.lazy.uniq {|i| i % 5000}.uniq {|i| i % 5000} 4 | N.times {enum.each {}} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/erb_render.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | require 'erb' 3 | 4 | data = < 6 | <%= title %> 7 | 8 |

<%= title %>

9 |

10 | <%= content %> 11 |

12 | 13 | 14 | erb 15 | 16 | title = "hello world!" 17 | content = "hello world!\n" * 10 18 | 19 | src = "def self.render(title, content); #{ERB.new(data).src}; end" 20 | mod = Module.new 21 | mod.instance_eval(src, "(ERB)") 22 | benchmark: 23 | erb_render: mod.render(title, content) 24 | loop_count: 1500000 25 | -------------------------------------------------------------------------------- /ruby/benchmark/fiber_chain.rb: -------------------------------------------------------------------------------- 1 | # Check performance of fiber creation and transfer. 2 | 3 | def make_link(previous) 4 | Fiber.new do 5 | while message = previous.resume 6 | Fiber.yield(message) 7 | end 8 | end 9 | end 10 | 11 | def make_chain(length, &block) 12 | chain = Fiber.new(&block) 13 | 14 | (length - 1).times do 15 | chain = make_link(chain) 16 | end 17 | 18 | return chain 19 | end 20 | 21 | def run_benchmark(length, repeats, message = :hello) 22 | chain = nil 23 | 24 | chain = make_chain(length) do 25 | while true 26 | Fiber.yield(message) 27 | end 28 | end 29 | 30 | repeats.times do 31 | abort "invalid result" unless chain.resume == message 32 | end 33 | end 34 | 35 | n = (ARGV[0] || 1000).to_i 36 | m = (ARGV[1] || 1000).to_i 37 | 38 | 5.times do 39 | run_benchmark(n, m) 40 | end 41 | -------------------------------------------------------------------------------- /ruby/benchmark/fiber_chain.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def make_link(previous) 3 | Fiber.new do 4 | while message = previous.resume 5 | Fiber.yield(message) 6 | end 7 | end 8 | end 9 | 10 | def make_chain(length = 1000, &block) 11 | chain = Fiber.new(&block) 12 | 13 | (length - 1).times do 14 | chain = make_link(chain) 15 | end 16 | 17 | return chain 18 | end 19 | 20 | message = "Hello World!" 21 | 22 | chain = make_chain do 23 | while true 24 | Fiber.yield(message) 25 | end 26 | end 27 | benchmark: 28 | make_chain: | 29 | make_chain(100) do 30 | while true 31 | Fiber.yield(message) 32 | end 33 | end 34 | resume_chain: | 35 | chain.resume 36 | loop_count: 5000 37 | -------------------------------------------------------------------------------- /ruby/benchmark/file_chmod.rb: -------------------------------------------------------------------------------- 1 | # chmod file 2 | require 'tempfile' 3 | max = 200_000 4 | tmp = Tempfile.new('chmod') 5 | path = tmp.path 6 | max.times do 7 | File.chmod(0777, path) 8 | end 9 | tmp.close! 10 | -------------------------------------------------------------------------------- /ruby/benchmark/file_rename.rb: -------------------------------------------------------------------------------- 1 | # rename file 2 | require 'tempfile' 3 | 4 | max = 100_000 5 | tmp = [ Tempfile.new('rename-a'), Tempfile.new('rename-b') ] 6 | a, b = tmp.map { |x| x.path } 7 | tmp.each { |t| t.close } # Windows can't rename files without closing them 8 | max.times do 9 | File.rename(a, b) 10 | File.rename(b, a) 11 | end 12 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_dsym.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | syms = ('a'..'z').map { |s| s.to_sym } 3 | syms.each { |s| h[s] = 1 } 4 | 200_000.times { syms.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_dsym_long.rb: -------------------------------------------------------------------------------- 1 | # [ruby-core:70129] [Bug #11396] 2 | collection_size = 200000 3 | sample_size = 10000 4 | 5 | values = (1..collection_size).to_a.map do |x| 6 | "THIS IS A LONGER STRING THAT IS ALSO UNIQUE #{x}" 7 | end 8 | 9 | symbol_hash = {} 10 | 11 | values.each do |x| 12 | symbol_hash[x.to_sym] = 1 13 | end 14 | 15 | # use the same samples each time to minimize deviations 16 | rng = Random.new(0) 17 | symbol_sample_array = values.sample(sample_size, random: rng).map(&:to_sym) 18 | 19 | 3000.times do 20 | symbol_sample_array.each { |x| symbol_hash[x] } 21 | end 22 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_fix.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | nums = (1..26).to_a 3 | nums.each { |i| h[i] = i } 4 | 200_000.times { nums.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_flo.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | strs = [*1..10000].map! {|i| i.fdiv(10)} 3 | strs.each { |s| h[s] = s } 4 | 50.times { strs.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_miss.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | strs = ('a'..'z').to_a.map!(&:freeze) 3 | strs.each { |s| h[s] = s } 4 | strs = ('A'..'Z').to_a 5 | 200_000.times { strs.each { |s| h[s] } } 6 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_str.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | strs = ('a'..'z').to_a.map!(&:freeze) 3 | strs.each { |s| h[s] = s } 4 | 200_000.times { strs.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_sym.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | syms = ('a'..'z').to_a 3 | begin 4 | syms = eval("%i[#{syms.join(' ')}]") 5 | rescue SyntaxError # <= 1.9.3 6 | syms.map!(&:to_sym) 7 | end 8 | syms.each { |s| h[s] = s } 9 | 200_000.times { syms.each { |s| h[s] } } 10 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_aref_sym_long.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | syms = %w[puts warn syswrite write stat bacon lettuce tomato 3 | some symbols in this array may already be interned others should not be 4 | hash browns make good breakfast but not cooked using prime numbers 5 | shift for division entries delete_if keys exist? 6 | ] 7 | begin 8 | syms = eval("%i[#{syms.join(' ')}]") 9 | rescue SyntaxError # <= 1.9.3 10 | syms.map!(&:to_sym) 11 | end 12 | syms.each { |s| h[s] = s } 13 | 200_000.times { syms.each { |s| h[s] } } 14 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_flatten.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | 10000.times do |i| 4 | h[i] = nil 5 | end 6 | 7 | 1000.times do 8 | h.flatten 9 | end 10 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_ident_flo.rb: -------------------------------------------------------------------------------- 1 | h = {}.compare_by_identity 2 | strs = (1..10000).to_a.map!(&:to_f) 3 | strs.each { |s| h[s] = s } 4 | 50.times { strs.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_ident_num.rb: -------------------------------------------------------------------------------- 1 | h = {}.compare_by_identity 2 | nums = (1..26).to_a 3 | nums.each { |n| h[n] = n } 4 | 200_000.times { nums.each { |n| h[n] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_ident_obj.rb: -------------------------------------------------------------------------------- 1 | h = {}.compare_by_identity 2 | objs = 26.times.map { Object.new } 3 | objs.each { |o| h[o] = o } 4 | 200_000.times { objs.each { |o| h[o] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_ident_str.rb: -------------------------------------------------------------------------------- 1 | h = {}.compare_by_identity 2 | strs = ('a'..'z').to_a 3 | strs.each { |s| h[s] = s } 4 | 200_000.times { strs.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_ident_sym.rb: -------------------------------------------------------------------------------- 1 | h = {}.compare_by_identity 2 | syms = ('a'..'z').to_a.map(&:to_sym) 3 | syms.each { |s| h[s] = s } 4 | 200_000.times { syms.each { |s| h[s] } } 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_keys.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | 10000.times do |i| 4 | h[i] = nil 5 | end 6 | 7 | 5000.times do 8 | h.keys 9 | end 10 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_literal_small2.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | 1_000_000.times.map { { "foo" => "bar", "bar" => "baz" } } 4 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_literal_small4.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | 1_000_000.times.map { { "foo" => "bar", "bar" => "baz", "baz" => "lol", "lol" => "lgtm" } } 4 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_literal_small8.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | 1_000_000.times.map { { "foo" => "bar", "bar" => "baz", "baz" => "lol", "lol" => "lgtm", "lgtm" => "nope", "nope" => "ok", "ok" => "again", "again" => "wait" } } 4 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_long.rb: -------------------------------------------------------------------------------- 1 | k1 = "Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong"; 2 | k2 = "Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping"; 3 | h = {k1 => 0, k2 => 0}; 4 | 3000000.times{|i| k = i % 2 ? k2 : k1; h [k] = h[k] + 1} 5 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_shift.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | 10000.times do |i| 4 | h[i] = nil 5 | end 6 | 7 | 50000.times do 8 | k, v = h.shift 9 | h[k] = v 10 | end 11 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_shift_u16.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | (16384..65536).each do |i| 4 | h[i] = nil 5 | end 6 | 7 | 300000.times do 8 | k, v = h.shift 9 | h[k] = v 10 | end 11 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_shift_u24.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | (0xff4000..0xffffff).each do |i| 4 | h[i] = nil 5 | end 6 | 7 | 300000.times do 8 | k, v = h.shift 9 | h[k] = v 10 | end 11 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_shift_u32.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | (0xffff4000..0xffffffff).each do |i| 4 | h[i] = nil 5 | end 6 | 7 | 300000.times do 8 | k, v = h.shift 9 | h[k] = v 10 | end 11 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_small2.rb: -------------------------------------------------------------------------------- 1 | 1000000.times.map{|i| a={}; 2.times{|j| a[j]=j}; a} 2 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_small4.rb: -------------------------------------------------------------------------------- 1 | 1000000.times.map{|i| a={}; 4.times{|j| a[j]=j}; a} 2 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_small8.rb: -------------------------------------------------------------------------------- 1 | 1000000.times.map{|i| a={}; 8.times{|j| a[j]=j}; a} 2 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_to_proc.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | 10000.times do |i| 4 | h[i] = nil 5 | end 6 | 7 | 5000.times do |i| 8 | [i].map(&h) 9 | end 10 | -------------------------------------------------------------------------------- /ruby/benchmark/hash_values.rb: -------------------------------------------------------------------------------- 1 | h = {} 2 | 3 | 10000.times do |i| 4 | h[i] = nil 5 | end 6 | 7 | 5000.times do 8 | h.values 9 | end 10 | -------------------------------------------------------------------------------- /ruby/benchmark/int_quo.rb: -------------------------------------------------------------------------------- 1 | 5000000.times { 42.quo(3) } 2 | -------------------------------------------------------------------------------- /ruby/benchmark/io_copy_stream_write.rb: -------------------------------------------------------------------------------- 1 | # The goal of this is to use a synthetic (non-IO) reader 2 | # to trigger the read/write loop of IO.copy_stream, 3 | # bypassing in-kernel mechanisms like sendfile for zero copy, 4 | # so we wrap the /dev/zero IO object: 5 | 6 | class Zero 7 | def initialize 8 | @n = 100000 9 | @in = File.open('/dev/zero', 'rb') 10 | end 11 | 12 | def read(len, buf) 13 | return if (@n -= 1) == 0 14 | @in.read(len, buf) 15 | end 16 | end 17 | 18 | begin 19 | src = Zero.new 20 | dst = File.open(IO::NULL, 'wb') 21 | n = IO.copy_stream(src, dst) 22 | rescue Errno::ENOENT 23 | # not *nix 24 | end if IO.respond_to?(:copy_stream) && IO.const_defined?(:NULL) 25 | -------------------------------------------------------------------------------- /ruby/benchmark/io_copy_stream_write_socket.rb: -------------------------------------------------------------------------------- 1 | # The goal of this is to use a synthetic (non-IO) reader 2 | # to trigger the read/write loop of IO.copy_stream, 3 | # bypassing in-kernel mechanisms like sendfile for zero copy, 4 | # so we wrap the /dev/zero IO object: 5 | class Zero 6 | def initialize 7 | @n = 100000 8 | @in = File.open('/dev/zero', 'rb') 9 | end 10 | 11 | def read(len, buf) 12 | return if (@n -= 1) == 0 13 | @in.read(len, buf) 14 | end 15 | end 16 | 17 | begin 18 | require 'socket' 19 | src = Zero.new 20 | rd, wr = UNIXSocket.pair 21 | pid = fork do 22 | wr.close 23 | buf = String.new 24 | while rd.read(16384, buf) 25 | end 26 | end 27 | rd.close 28 | IO.copy_stream(src, wr) 29 | rescue Errno::ENOENT, NotImplementedError, NameError 30 | # not *nix: missing /dev/zero, fork, or UNIXSocket 31 | rescue LoadError # no socket? 32 | ensure 33 | wr.close if wr 34 | Process.waitpid(pid) if pid 35 | end if IO.respond_to?(:copy_stream) 36 | -------------------------------------------------------------------------------- /ruby/benchmark/io_file_create.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Create files 3 | # 4 | 5 | max = 200_000 6 | file = './tmpfile_of_bm_io_file_create' 7 | 8 | max.times{ 9 | f = open(file, 'w') 10 | f.close#(true) 11 | } 12 | File.unlink(file) 13 | 14 | -------------------------------------------------------------------------------- /ruby/benchmark/io_file_read.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Seek and Read file. 3 | # 4 | 5 | require 'tempfile' 6 | 7 | max = 200_000 8 | str = "Hello world! " * 1000 9 | f = Tempfile.new('yarv-benchmark') 10 | f.write str 11 | 12 | max.times{ 13 | f.seek 0 14 | f.read 15 | } 16 | -------------------------------------------------------------------------------- /ruby/benchmark/io_file_write.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Seek and Write file. 3 | # 4 | 5 | require 'tempfile' 6 | 7 | max = 200_000 8 | str = "Hello world! " * 1000 9 | f = Tempfile.new('yarv-benchmark') 10 | 11 | max.times{ 12 | f.seek 0 13 | f.write str 14 | } 15 | -------------------------------------------------------------------------------- /ruby/benchmark/io_nonblock_noex.rb: -------------------------------------------------------------------------------- 1 | nr = 1_000_000 2 | i = 0 3 | msg = '.' 4 | buf = '.' 5 | noex = { exception: false } 6 | begin 7 | r, w = IO.pipe 8 | while i < nr 9 | i += 1 10 | w.write_nonblock(msg, **noex) 11 | r.read_nonblock(1, buf, **noex) 12 | end 13 | rescue ArgumentError # old Rubies 14 | while i < nr 15 | i += 1 16 | w.write_nonblock(msg) 17 | r.read_nonblock(1, buf) 18 | end 19 | ensure 20 | r.close 21 | w.close 22 | end 23 | -------------------------------------------------------------------------------- /ruby/benchmark/io_nonblock_noex2.rb: -------------------------------------------------------------------------------- 1 | nr = 1_000_000 2 | i = 0 3 | msg = '.' 4 | buf = '.' 5 | begin 6 | r, w = IO.pipe 7 | while i < nr 8 | i += 1 9 | w.write_nonblock(msg, exception: false) 10 | r.read_nonblock(1, buf, exception: false) 11 | end 12 | rescue ArgumentError # old Rubies 13 | while i < nr 14 | i += 1 15 | w.write_nonblock(msg) 16 | r.read_nonblock(1, buf) 17 | end 18 | ensure 19 | r.close 20 | w.close 21 | end 22 | -------------------------------------------------------------------------------- /ruby/benchmark/io_pipe_rw.rb: -------------------------------------------------------------------------------- 1 | # Measure uncontended GVL performance via read/write with 1:1 threading 2 | # If we switch to M:N threading, this will benchmark something else... 3 | r, w = IO.pipe 4 | src = '0'.freeze 5 | dst = String.new 6 | i = 0 7 | while i < 1_000_000 8 | i += 1 9 | w.write(src) 10 | r.read(1, dst) 11 | end 12 | w.close 13 | r.close 14 | -------------------------------------------------------------------------------- /ruby/benchmark/io_select.rb: -------------------------------------------------------------------------------- 1 | # IO.select performance 2 | 3 | w = [ IO.pipe[1] ]; 4 | 5 | nr = 1000000 6 | nr.times { 7 | IO.select nil, w 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ruby/benchmark/io_select2.rb: -------------------------------------------------------------------------------- 1 | # IO.select performance. worst case of single fd. 2 | 3 | ios = [] 4 | nr = 1000000 5 | if defined?(Process::RLIMIT_NOFILE) 6 | max = Process.getrlimit(Process::RLIMIT_NOFILE)[0] 7 | else 8 | max = 64 9 | end 10 | puts "max fd: #{max} (results not apparent with <= 1024 max fd)" 11 | 12 | ((max / 2) - 10).times do 13 | ios.concat IO.pipe 14 | end 15 | 16 | last = [ ios[-1] ] 17 | puts "last IO: #{last[0].inspect}" 18 | 19 | nr.times do 20 | IO.select nil, last 21 | end 22 | 23 | -------------------------------------------------------------------------------- /ruby/benchmark/io_select3.rb: -------------------------------------------------------------------------------- 1 | # IO.select performance. a lot of fd 2 | 3 | ios = [] 4 | nr = 100 5 | if defined?(Process::RLIMIT_NOFILE) 6 | max = Process.getrlimit(Process::RLIMIT_NOFILE)[0] 7 | else 8 | max = 64 9 | end 10 | puts "max fd: #{max} (results not apparent with <= 1024 max fd)" 11 | 12 | (max - 10).times do 13 | r, w = IO.pipe 14 | r.close 15 | ios.push w 16 | end 17 | 18 | nr.times do 19 | IO.select nil, ios 20 | end 21 | 22 | -------------------------------------------------------------------------------- /ruby/benchmark/irb_color.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | require 'irb/color' 3 | code = <<~'CODE' 4 | def self.foo # bar 5 | :"erb #{ERB.new("<%= self %>", trim_mode: ?-).result}" 6 | end 7 | CODE 8 | benchmark: 9 | irb_color_complete: | 10 | IRB::Color.colorize_code(code, complete: true) 11 | irb_color_incomplete: | 12 | IRB::Color.colorize_code(code, complete: false) 13 | loop_count: 2000000 14 | -------------------------------------------------------------------------------- /ruby/benchmark/irb_exec.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | # frozen_string_literal: true 3 | require 'rbconfig' 4 | irb_f = [File.join(File.dirname(RbConfig.ruby), 'irb'), '-f'] 5 | benchmark: 6 | irb_exec: | 7 | IO.popen(irb_f, 'w') do |io| 8 | io.write('exit') 9 | end 10 | loop_count: 30 11 | -------------------------------------------------------------------------------- /ruby/benchmark/loop_for.rb: -------------------------------------------------------------------------------- 1 | for i in 1..30_000_000 2 | # 3 | end 4 | -------------------------------------------------------------------------------- /ruby/benchmark/loop_generator.rb: -------------------------------------------------------------------------------- 1 | max = 600000 2 | 3 | if defined? Fiber 4 | gen = (1..max).each 5 | loop do 6 | gen.next 7 | end 8 | else 9 | require 'generator' 10 | gen = Generator.new((0..max)) 11 | while gen.next? 12 | gen.next 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /ruby/benchmark/loop_times.rb: -------------------------------------------------------------------------------- 1 | 30_000_000.times{|e|} 2 | -------------------------------------------------------------------------------- /ruby/benchmark/loop_whileloop.rb: -------------------------------------------------------------------------------- 1 | i = 0 2 | while i<30_000_000 # benchmark loop 1 3 | i += 1 4 | end 5 | -------------------------------------------------------------------------------- /ruby/benchmark/loop_whileloop2.rb: -------------------------------------------------------------------------------- 1 | i = 0 2 | while i< 6_000_000 # benchmark loop 2 3 | i += 1 4 | end 5 | -------------------------------------------------------------------------------- /ruby/benchmark/marshal_dump_flo.rb: -------------------------------------------------------------------------------- 1 | bug10761 = 10000.times.map { |x| x.to_f } 2 | 100.times { Marshal.dump(bug10761) } 3 | -------------------------------------------------------------------------------- /ruby/benchmark/marshal_dump_load_geniv.rb: -------------------------------------------------------------------------------- 1 | a = '' 2 | a.instance_eval do 3 | @a = :a 4 | @b = :b 5 | @c = :c 6 | end 7 | 100000.times do 8 | a = Marshal.load(Marshal.dump(a)) 9 | end 10 | #p(a.instance_eval { @a == :a && @b == :b && @c == :c }) 11 | -------------------------------------------------------------------------------- /ruby/benchmark/marshal_dump_load_time.rb: -------------------------------------------------------------------------------- 1 | 100000.times { Marshal.load(Marshal.dump(Time.now)) } 2 | -------------------------------------------------------------------------------- /ruby/benchmark/match_gt4.rb: -------------------------------------------------------------------------------- 1 | 1000000.times { /(.)(.)(\d+)(\d)/.match("THX1138.") } 2 | -------------------------------------------------------------------------------- /ruby/benchmark/match_small.rb: -------------------------------------------------------------------------------- 1 | 1000000.times { 'haystack'.match(/hay/) } 2 | -------------------------------------------------------------------------------- /ruby/benchmark/range_last.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | - (1..1_000_000).last(100) 3 | - (1..1_000_000).last(1000) 4 | - (1..1_000_000).last(10000) 5 | -------------------------------------------------------------------------------- /ruby/benchmark/realpath.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | f = File 3 | pwd = Dir.pwd 4 | Dir.mkdir('b') unless f.directory?('b') 5 | f.write('b/a', '') unless f.file?('b/a') 6 | 7 | relative = 'b/a' 8 | absolute = File.join(pwd, relative) 9 | dir = 'b' 10 | file = 'a' 11 | 12 | relative_dir = 'b/c' 13 | absolute_dir = File.join(pwd, relative_dir) 14 | file_dir = 'c' 15 | benchmark: 16 | relative_nil: "f.realpath(relative, nil)" 17 | absolute_nil: "f.realpath(absolute, nil)" 18 | relative_relative: "f.realpath(file, dir)" 19 | absolute_relative: "f.realpath(absolute, dir)" 20 | relative_absolute: "f.realpath(relative, pwd)" 21 | relative_nil_dir: "f.realdirpath(relative_dir, nil)" 22 | absolute_nil_dir: "f.realdirpath(absolute_dir, nil)" 23 | relative_relative_dir: "f.realdirpath(file_dir, dir)" 24 | absolute_relative_dir: "f.realdirpath(absolute_dir, dir)" 25 | relative_absolute_dir: "f.realdirpath(relative_dir, pwd)" 26 | relative_nil_notexist: "f.realpath(relative_dir, nil) rescue nil" 27 | absolute_nil_notexist: "f.realpath(absolute_dir, nil) rescue nil" 28 | relative_relative_notexist: "f.realpath(file_dir, dir) rescue nil" 29 | absolute_relative_notexist: "f.realpath(absolute_dir, dir) rescue nil" 30 | relative_absolute_notexist: "f.realpath(relative_dir, pwd) rescue nil" 31 | -------------------------------------------------------------------------------- /ruby/benchmark/require.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | require "fileutils" 3 | 4 | def prepare 5 | num_files = 10000 6 | 7 | basename = File.dirname($0) 8 | data_dir = File.join(basename, "bm_require.data") 9 | 10 | # skip if all of files exists 11 | if File.exist?(File.join(data_dir, "c#{num_files}.rb")) 12 | return 13 | end 14 | 15 | FileUtils.mkdir_p(data_dir) 16 | 17 | 1.upto(num_files) do |i| 18 | f = File.open("#{data_dir}/c#{i}.rb", "w") 19 | f.puts <<-END 20 | class C#{i} 21 | end 22 | END 23 | end 24 | end 25 | 26 | prepare 27 | benchmark: 28 | require: | 29 | $:.push File.join(File.dirname(__FILE__), "bm_require.data") 30 | 31 | 1.upto(10000) do |i| 32 | require "c#{i}" 33 | end 34 | 35 | $:.pop 36 | loop_count: 1 37 | -------------------------------------------------------------------------------- /ruby/benchmark/require_thread.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | require "fileutils" 3 | 4 | def prepare 5 | num_files = 10000 6 | 7 | basename = File.dirname($0) 8 | data_dir = File.join(basename, "bm_require.data") 9 | 10 | # skip if all of files exists 11 | if File.exist?(File.join(data_dir, "c#{num_files}.rb")) 12 | return 13 | end 14 | 15 | FileUtils.mkdir_p(data_dir) 16 | 17 | 1.upto(num_files) do |i| 18 | f = File.open("#{data_dir}/c#{i}.rb", "w") 19 | f.puts <<-END 20 | class C#{i} 21 | end 22 | END 23 | end 24 | end 25 | 26 | prepare 27 | benchmark: 28 | require_thread: | 29 | $:.push File.join(File.dirname(__FILE__), "bm_require.data") 30 | 31 | i=0 32 | t = Thread.new do 33 | while true 34 | i = i+1 # dummy loop 35 | end 36 | end 37 | 38 | 1.upto(100) do |i| 39 | require "c#{i}" 40 | end 41 | 42 | $:.pop 43 | t.kill 44 | loop_count: 1 45 | -------------------------------------------------------------------------------- /ruby/benchmark/securerandom.rb: -------------------------------------------------------------------------------- 1 | require "securerandom" 2 | 3 | 20_0000.times do 4 | SecureRandom.random_number(100) 5 | end 6 | -------------------------------------------------------------------------------- /ruby/benchmark/so_ackermann.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: ackermann-ruby.code,v 1.4 2004/11/13 07:40:41 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | 6 | def ack(m, n) 7 | if m == 0 then 8 | n + 1 9 | elsif n == 0 then 10 | ack(m - 1, 1) 11 | else 12 | ack(m - 1, ack(m, n - 1)) 13 | end 14 | end 15 | 16 | NUM = 9 17 | ack(3, NUM) 18 | 19 | 20 | -------------------------------------------------------------------------------- /ruby/benchmark/so_array.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: ary-ruby.code,v 1.4 2004/11/13 07:41:27 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | # with help from Paul Brannan and Mark Hubbart 6 | 7 | n = 9000 # Integer(ARGV.shift || 1) 8 | 9 | x = Array.new(n) 10 | y = Array.new(n, 0) 11 | 12 | n.times{|bi| 13 | x[bi] = bi + 1 14 | } 15 | 16 | (0 .. 999).each do |e| 17 | (n-1).step(0,-1) do |bi| 18 | y[bi] += x.at(bi) 19 | end 20 | end 21 | # puts "#{y.first} #{y.last}" 22 | 23 | 24 | -------------------------------------------------------------------------------- /ruby/benchmark/so_binary_trees.rb: -------------------------------------------------------------------------------- 1 | # The Computer Language Shootout Benchmarks 2 | # http://shootout.alioth.debian.org 3 | # 4 | # contributed by Jesse Millikan 5 | 6 | # disable output 7 | alias puts_orig puts 8 | def puts str 9 | # disable puts 10 | end 11 | 12 | def item_check(tree) 13 | if tree[0] == nil 14 | tree[1] 15 | else 16 | tree[1] + item_check(tree[0]) - item_check(tree[2]) 17 | end 18 | end 19 | 20 | def bottom_up_tree(item, depth) 21 | if depth > 0 22 | item_item = 2 * item 23 | depth -= 1 24 | [bottom_up_tree(item_item - 1, depth), item, bottom_up_tree(item_item, depth)] 25 | else 26 | [nil, item, nil] 27 | end 28 | end 29 | 30 | max_depth = 16 # ARGV[0].to_i 31 | min_depth = 4 32 | 33 | max_depth = min_depth + 2 if min_depth + 2 > max_depth 34 | 35 | stretch_depth = max_depth + 1 36 | stretch_tree = bottom_up_tree(0, stretch_depth) 37 | 38 | puts "stretch tree of depth #{stretch_depth}\t check: #{item_check(stretch_tree)}" 39 | stretch_tree = nil 40 | 41 | long_lived_tree = bottom_up_tree(0, max_depth) 42 | 43 | min_depth.step(max_depth + 1, 2) do |depth| 44 | iterations = 2**(max_depth - depth + min_depth) 45 | 46 | check = 0 47 | 48 | for i in 1..iterations 49 | temp_tree = bottom_up_tree(i, depth) 50 | check += item_check(temp_tree) 51 | 52 | temp_tree = bottom_up_tree(-i, depth) 53 | check += item_check(temp_tree) 54 | end 55 | 56 | puts "#{iterations * 2}\t trees of depth #{depth}\t check: #{check}" 57 | end 58 | 59 | puts "long lived tree of depth #{max_depth}\t check: #{item_check(long_lived_tree)}" 60 | 61 | undef puts 62 | alias puts puts_orig 63 | -------------------------------------------------------------------------------- /ruby/benchmark/so_concatenate.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: strcat-ruby.code,v 1.4 2004/11/13 07:43:28 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | # based on code from Aristarkh A Zagorodnikov and Dat Nguyen 6 | 7 | STUFF = "hello\n" 8 | i = 0 9 | while i<10 10 | i += 1 11 | hello = '' 12 | 4_000_000.times do |e| 13 | hello << STUFF 14 | end 15 | end 16 | # puts hello.length 17 | 18 | 19 | -------------------------------------------------------------------------------- /ruby/benchmark/so_exception.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: except-ruby.code,v 1.4 2004/11/13 07:41:33 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | 6 | $HI = 0 7 | $LO = 0 8 | NUM = 250000 # Integer(ARGV[0] || 1) 9 | 10 | 11 | class Lo_Exception < Exception 12 | def initialize(num) 13 | @value = num 14 | end 15 | end 16 | 17 | class Hi_Exception < Exception 18 | def initialize(num) 19 | @value = num 20 | end 21 | end 22 | 23 | def some_function(num) 24 | begin 25 | hi_function(num) 26 | rescue 27 | print "We shouldn't get here, exception is: #{$!.type}\n" 28 | end 29 | end 30 | 31 | def hi_function(num) 32 | begin 33 | lo_function(num) 34 | rescue Hi_Exception 35 | $HI = $HI + 1 36 | end 37 | end 38 | 39 | def lo_function(num) 40 | begin 41 | blowup(num) 42 | rescue Lo_Exception 43 | $LO = $LO + 1 44 | end 45 | end 46 | 47 | def blowup(num) 48 | if num % 2 == 0 49 | raise Lo_Exception.new(num) 50 | else 51 | raise Hi_Exception.new(num) 52 | end 53 | end 54 | 55 | 56 | i = 1 57 | max = NUM+1 58 | while i < max 59 | i += 1 60 | some_function(i+1) 61 | end 62 | -------------------------------------------------------------------------------- /ruby/benchmark/so_fannkuch.rb: -------------------------------------------------------------------------------- 1 | # The Computer Language Shootout 2 | # http://shootout.alioth.debian.org/ 3 | # Contributed by Sokolov Yura 4 | # Modified by Ryan Williams 5 | 6 | def fannkuch(n) 7 | maxFlips, m, r, check = 0, n-1, n, 0 8 | count = (1..n).to_a 9 | perm = (1..n).to_a 10 | 11 | while true 12 | if check < 30 13 | puts "#{perm}" 14 | check += 1 15 | end 16 | 17 | while r != 1 18 | count[r-1] = r 19 | r -= 1 20 | end 21 | 22 | if perm[0] != 1 and perm[m] != n 23 | perml = perm.clone #.dup 24 | flips = 0 25 | while (k = perml.first ) != 1 26 | perml = perml.slice!(0, k).reverse + perml 27 | flips += 1 28 | end 29 | maxFlips = flips if flips > maxFlips 30 | end 31 | while true 32 | if r==n then return maxFlips end 33 | perm.insert r,perm.shift 34 | break if (count[r] -= 1) > 0 35 | r += 1 36 | end 37 | end 38 | end 39 | 40 | def puts *args 41 | end 42 | 43 | N = 9 # (ARGV[0] || 1).to_i 44 | puts "Pfannkuchen(#{N}) = #{fannkuch(N)}" 45 | 46 | -------------------------------------------------------------------------------- /ruby/benchmark/so_fasta.rb: -------------------------------------------------------------------------------- 1 | # The Computer Language Shootout 2 | # http://shootout.alioth.debian.org/ 3 | # Contributed by Sokolov Yura 4 | 5 | $last = 42.0 6 | def gen_random(max, im=139968, ia=3877, ic=29573) 7 | (max * ($last = ($last * ia + ic) % im)) / im 8 | end 9 | 10 | alu = 11 | "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"+ 12 | "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"+ 13 | "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"+ 14 | "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"+ 15 | "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"+ 16 | "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"+ 17 | "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA" 18 | 19 | iub = [ 20 | ["a", 0.27], 21 | ["c", 0.12], 22 | ["g", 0.12], 23 | ["t", 0.27], 24 | 25 | ["B", 0.02], 26 | ["D", 0.02], 27 | ["H", 0.02], 28 | ["K", 0.02], 29 | ["M", 0.02], 30 | ["N", 0.02], 31 | ["R", 0.02], 32 | ["S", 0.02], 33 | ["V", 0.02], 34 | ["W", 0.02], 35 | ["Y", 0.02], 36 | ] 37 | homosapiens = [ 38 | ["a", 0.3029549426680], 39 | ["c", 0.1979883004921], 40 | ["g", 0.1975473066391], 41 | ["t", 0.3015094502008], 42 | ] 43 | 44 | def make_repeat_fasta(id, desc, src, n) 45 | puts ">#{id} #{desc}" 46 | v = nil 47 | width = 60 48 | l = src.length 49 | s = src * ((n / l) + 1) 50 | s.slice!(n, l) 51 | puts(s.scan(/.{1,#{width}}/).join("\n")) 52 | end 53 | 54 | def make_random_fasta(id, desc, table, n) 55 | puts ">#{id} #{desc}" 56 | rand, v = nil,nil 57 | width = 60 58 | chunk = 1 * width 59 | prob = 0.0 60 | table.each{|v| v[1]= (prob += v[1])} 61 | for i in 1..(n/width) 62 | puts((1..width).collect{ 63 | rand = gen_random(1.0) 64 | table.find{|v| v[1]>rand}[0] 65 | }.join) 66 | end 67 | if n%width != 0 68 | puts((1..(n%width)).collect{ 69 | rand = gen_random(1.0) 70 | table.find{|v| v[1]>rand}[0] 71 | }.join) 72 | end 73 | end 74 | 75 | 76 | n = (ARGV[0] or 250_000).to_i 77 | 78 | make_repeat_fasta('ONE', 'Homo sapiens alu', alu, n*2) 79 | make_random_fasta('TWO', 'IUB ambiguity codes', iub, n*3) 80 | make_random_fasta('THREE', 'Homo sapiens frequency', homosapiens, n*5) 81 | 82 | -------------------------------------------------------------------------------- /ruby/benchmark/so_lists.rb: -------------------------------------------------------------------------------- 1 | #from http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby 2 | 3 | NUM = 300 4 | SIZE = 10000 5 | 6 | def test_lists() 7 | # create a list of integers (Li1) from 1 to SIZE 8 | li1 = (1..SIZE).to_a 9 | # copy the list to li2 (not by individual items) 10 | li2 = li1.dup 11 | # remove each individual item from left side of li2 and 12 | # append to right side of li3 (preserving order) 13 | li3 = Array.new 14 | while (not li2.empty?) 15 | li3.push(li2.shift) 16 | end 17 | # li2 must now be empty 18 | # remove each individual item from right side of li3 and 19 | # append to right side of li2 (reversing list) 20 | while (not li3.empty?) 21 | li2.push(li3.pop) 22 | end 23 | # li3 must now be empty 24 | # reverse li1 in place 25 | li1.reverse! 26 | # check that first item is now SIZE 27 | if li1[0] != SIZE then 28 | p "not SIZE" 29 | 0 30 | else 31 | # compare li1 and li2 for equality 32 | if li1 != li2 then 33 | return(0) 34 | else 35 | # return the length of the list 36 | li1.length 37 | end 38 | end 39 | end 40 | 41 | i = 0 42 | while i LIMIT_SQUARED 36 | escape = true 37 | break 38 | end 39 | end 40 | 41 | byte_acc = (byte_acc << 1) | (escape ? 0b0 : 0b1) 42 | bit_num += 1 43 | 44 | # Code is very similar for these cases, but using separate blocks 45 | # ensures we skip the shifting when it's unnecessary, which is most cases. 46 | if (bit_num == 8) 47 | print byte_acc.chr 48 | byte_acc = 0 49 | bit_num = 0 50 | elsif (x == count_size) 51 | byte_acc <<= (8 - bit_num) 52 | print byte_acc.chr 53 | byte_acc = 0 54 | bit_num = 0 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /ruby/benchmark/so_matrix.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: matrix-ruby.code,v 1.4 2004/11/13 07:42:14 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | 6 | n = 60 #Integer(ARGV.shift || 1) 7 | 8 | size = 40 9 | 10 | def mkmatrix(rows, cols) 11 | count = 1 12 | mx = Array.new(rows) 13 | (0 .. (rows - 1)).each do |bi| 14 | row = Array.new(cols, 0) 15 | (0 .. (cols - 1)).each do |j| 16 | row[j] = count 17 | count += 1 18 | end 19 | mx[bi] = row 20 | end 21 | mx 22 | end 23 | 24 | def mmult(rows, cols, m1, m2) 25 | m3 = Array.new(rows) 26 | (0 .. (rows - 1)).each do |bi| 27 | row = Array.new(cols, 0) 28 | (0 .. (cols - 1)).each do |j| 29 | val = 0 30 | (0 .. (cols - 1)).each do |k| 31 | val += m1.at(bi).at(k) * m2.at(k).at(j) 32 | end 33 | row[j] = val 34 | end 35 | m3[bi] = row 36 | end 37 | m3 38 | end 39 | 40 | m1 = mkmatrix(size, size) 41 | m2 = mkmatrix(size, size) 42 | mm = Array.new 43 | n.times do 44 | mm = mmult(size, size, m1, m2) 45 | end 46 | # puts "#{mm[0][0]} #{mm[2][3]} #{mm[3][2]} #{mm[4][4]}" 47 | 48 | 49 | -------------------------------------------------------------------------------- /ruby/benchmark/so_nested_loop.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: nestedloop-ruby.code,v 1.4 2004/11/13 07:42:22 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | # from Avi Bryant 6 | 7 | n = 16 # Integer(ARGV.shift || 1) 8 | x = 0 9 | n.times do 10 | n.times do 11 | n.times do 12 | n.times do 13 | n.times do 14 | n.times do 15 | x += 1 16 | end 17 | end 18 | end 19 | end 20 | end 21 | end 22 | # puts x 23 | 24 | 25 | -------------------------------------------------------------------------------- /ruby/benchmark/so_nsieve.rb: -------------------------------------------------------------------------------- 1 | # The Computer Language Shootout 2 | # http://shootout.alioth.debian.org/ 3 | # 4 | # contributed by Glenn Parker, March 2005 5 | # modified by Evan Phoenix, Sept 2006 6 | 7 | def sieve(m) 8 | flags = Flags.dup[0,m] 9 | count = 0 10 | pmax = m - 1 11 | p = 2 12 | while p <= pmax 13 | unless flags[p].zero? 14 | count += 1 15 | mult = p 16 | while mult <= pmax 17 | flags[mult] = 0 18 | mult += p 19 | end 20 | end 21 | p += 1 22 | end 23 | count 24 | end 25 | 26 | n = 9 # (ARGV[0] || 2).to_i 27 | Flags = ("\x1" * ( 2 ** n * 10_000)).unpack("c*") 28 | 29 | n.downto(n-2) do |exponent| 30 | break if exponent < 0 31 | m = (1 << exponent) * 10_000 32 | # m = (2 ** exponent) * 10_000 33 | count = sieve(m) 34 | printf "Primes up to %8d %8d\n", m, count 35 | end 36 | -------------------------------------------------------------------------------- /ruby/benchmark/so_nsieve_bits.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | #coding: us-ascii 3 | # 4 | # The Great Computer Language Shootout 5 | # http://shootout.alioth.debian.org/ 6 | # 7 | # nsieve-bits in Ruby 8 | # Contributed by Glenn Parker, March 2005 9 | 10 | CharExponent = 3 11 | BitsPerChar = 1 << CharExponent 12 | LowMask = BitsPerChar - 1 13 | 14 | def sieve(m) 15 | items = "\xFF" * ((m / BitsPerChar) + 1) 16 | masks = "" 17 | BitsPerChar.times do |b| 18 | masks << (1 << b).chr 19 | end 20 | 21 | count = 0 22 | pmax = m - 1 23 | 2.step(pmax, 1) do |p| 24 | if items[p >> CharExponent][p & LowMask] == 1 25 | count += 1 26 | p.step(pmax, p) do |mult| 27 | a = mult >> CharExponent 28 | b = mult & LowMask 29 | items[a] -= masks[b] if items[a][b] != 0 30 | end 31 | end 32 | end 33 | count 34 | end 35 | 36 | n = 9 # (ARGV[0] || 2).to_i 37 | n.step(n - 2, -1) do |exponent| 38 | break if exponent < 0 39 | m = 2 ** exponent * 10_000 40 | count = sieve(m) 41 | printf "Primes up to %8d %8d\n", m, count 42 | end 43 | 44 | -------------------------------------------------------------------------------- /ruby/benchmark/so_object.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # -*- mode: ruby -*- 3 | # $Id: objinst-ruby.code,v 1.4 2004/11/13 07:42:25 bfulgham Exp $ 4 | # http://www.bagley.org/~doug/shootout/ 5 | # with help from Aristarkh Zagorodnikov 6 | 7 | class Toggle 8 | def initialize(start_state) 9 | @bool = start_state 10 | end 11 | 12 | def value 13 | @bool 14 | end 15 | 16 | def activate 17 | @bool = !@bool 18 | self 19 | end 20 | end 21 | 22 | class NthToggle < Toggle 23 | def initialize(start_state, max_counter) 24 | super start_state 25 | @count_max = max_counter 26 | @counter = 0 27 | end 28 | 29 | def activate 30 | @counter += 1 31 | if @counter >= @count_max 32 | @bool = !@bool 33 | @counter = 0 34 | end 35 | self 36 | end 37 | end 38 | 39 | n = 1500000 # (ARGV.shift || 1).to_i 40 | 41 | toggle = Toggle.new 1 42 | 5.times do 43 | toggle.activate.value ? 'true' : 'false' 44 | end 45 | n.times do 46 | toggle = Toggle.new 1 47 | end 48 | 49 | ntoggle = NthToggle.new 1, 3 50 | 8.times do 51 | ntoggle.activate.value ? 'true' : 'false' 52 | end 53 | n.times do 54 | ntoggle = NthToggle.new 1, 3 55 | end 56 | 57 | -------------------------------------------------------------------------------- /ruby/benchmark/so_partial_sums.rb: -------------------------------------------------------------------------------- 1 | n = 2_500_000 # (ARGV.shift || 1).to_i 2 | 3 | alt = 1.0 ; s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = 0.0 4 | 5 | 1.upto(n) do |d| 6 | d = d.to_f ; d2 = d * d ; d3 = d2 * d ; ds = Math.sin(d) ; dc = Math.cos(d) 7 | 8 | s0 += (2.0 / 3.0) ** (d - 1.0) 9 | s1 += 1.0 / Math.sqrt(d) 10 | s2 += 1.0 / (d * (d + 1.0)) 11 | s3 += 1.0 / (d3 * ds * ds) 12 | s4 += 1.0 / (d3 * dc * dc) 13 | s5 += 1.0 / d 14 | s6 += 1.0 / d2 15 | s7 += alt / d 16 | s8 += alt / (2.0 * d - 1.0) 17 | 18 | alt = -alt 19 | end 20 | 21 | if false 22 | printf("%.9f\t(2/3)^k\n", s0) 23 | printf("%.9f\tk^-0.5\n", s1) 24 | printf("%.9f\t1/k(k+1)\n", s2) 25 | printf("%.9f\tFlint Hills\n", s3) 26 | printf("%.9f\tCookson Hills\n", s4) 27 | printf("%.9f\tHarmonic\n", s5) 28 | printf("%.9f\tRiemann Zeta\n", s6) 29 | printf("%.9f\tAlternating Harmonic\n", s7) 30 | printf("%.9f\tGregory\n", s8) 31 | end 32 | -------------------------------------------------------------------------------- /ruby/benchmark/so_pidigits.rb: -------------------------------------------------------------------------------- 1 | # The Great Computer Language Shootout 2 | # http://shootout.alioth.debian.org/ 3 | # 4 | # contributed by Gabriele Renzi 5 | 6 | class PiDigitSpigot 7 | 8 | def initialize() 9 | @z = Transformation.new 1,0,0,1 10 | @x = Transformation.new 0,0,0,0 11 | @inverse = Transformation.new 0,0,0,0 12 | end 13 | 14 | def next! 15 | @y = @z.extract(3) 16 | if safe? @y 17 | @z = produce(@y) 18 | @y 19 | else 20 | @z = consume @x.next!() 21 | next!() 22 | end 23 | end 24 | 25 | def safe?(digit) 26 | digit == @z.extract(4) 27 | end 28 | 29 | def produce(i) 30 | @inverse.qrst(10,-10*i,0,1).compose(@z) 31 | end 32 | 33 | def consume(a) 34 | @z.compose(a) 35 | end 36 | end 37 | 38 | 39 | class Transformation 40 | attr_reader :q, :r, :s, :t 41 | def initialize(q, r, s, t) 42 | @q,@r,@s,@t,@k = q,r,s,t,0 43 | end 44 | 45 | def next!() 46 | @q = @k = @k + 1 47 | @r = 4 * @k + 2 48 | @s = 0 49 | @t = 2 * @k + 1 50 | self 51 | end 52 | 53 | def extract(j) 54 | (@q * j + @r) / (@s * j + @t) 55 | end 56 | 57 | def compose(a) 58 | self.class.new( @q * a.q, 59 | @q * a.r + r * a.t, 60 | @s * a.q + t * a.s, 61 | @s * a.r + t * a.t 62 | ) 63 | end 64 | 65 | def qrst *args 66 | initialize *args 67 | self 68 | end 69 | 70 | 71 | end 72 | 73 | 74 | WIDTH = 10 75 | n = 2_500 # Integer(ARGV[0]) 76 | j = 0 77 | 78 | digits = PiDigitSpigot.new 79 | 80 | while n > 0 81 | if n >= WIDTH 82 | WIDTH.times {print digits.next!} 83 | j += WIDTH 84 | else 85 | n.times {print digits.next!} 86 | (WIDTH-n).times {print " "} 87 | j += n 88 | end 89 | puts "\t:"+j.to_s 90 | n -= WIDTH 91 | end 92 | 93 | -------------------------------------------------------------------------------- /ruby/benchmark/so_random.rb: -------------------------------------------------------------------------------- 1 | # from http://www.bagley.org/~doug/shootout/bench/random/random.ruby 2 | 3 | IM = 139968.0 4 | IA = 3877.0 5 | IC = 29573.0 6 | 7 | $last = 42.0 8 | 9 | def gen_random(max) 10 | (max * ($last = ($last * IA + IC) % IM)) / IM 11 | end 12 | 13 | N = 3_000_000 14 | 15 | i = 0 16 | while i= "2.2.0" 5 | GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) 6 | end 7 | 8 | short_lived = '' 9 | benchmark: 10 | vm1_gc_wb_ary: | 11 | short_lived_ary[0] = short_lived # write barrier 12 | loop_count: 30000000 13 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_gc_wb_ary_promoted.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | long_lived = [] 3 | 4 | if RUBY_VERSION > "2.2.0" 5 | 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) } 6 | elsif 7 | GC.start 8 | end 9 | 10 | short_lived = '' 11 | 12 | benchmark: 13 | vm1_gc_wb_ary_promoted: | 14 | long_lived[0] = short_lived # write barrier 15 | loop_count: 30000000 16 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_gc_wb_obj.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class C 3 | attr_accessor :foo 4 | end 5 | short_lived_obj = C.new 6 | 7 | if RUBY_VERSION >= "2.2.0" 8 | GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) 9 | end 10 | 11 | short_lived = '' 12 | benchmark: 13 | vm1_gc_wb_obj: | 14 | short_lived_obj.foo = short_lived # write barrier 15 | loop_count: 30000000 16 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_gc_wb_obj_promoted.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class C 3 | attr_accessor :foo 4 | end 5 | long_lived = C.new 6 | 7 | if RUBY_VERSION >= "2.2.0" 8 | 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) } 9 | elsif 10 | GC.start 11 | end 12 | 13 | short_lived = '' 14 | benchmark: 15 | vm1_gc_wb_obj_promoted: | 16 | long_lived.foo = short_lived # write barrier 17 | loop_count: 30000000 18 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_ivar.yml: -------------------------------------------------------------------------------- 1 | prelude: "@a = 1\n" 2 | benchmark: 3 | vm1_ivar: | 4 | j = @a 5 | k = @a 6 | loop_count: 30000000 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_ivar_set.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm1_ivar_set: | 3 | @a = 1 4 | @b = 2 5 | loop_count: 30000000 6 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_length.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | a = 'abc' 3 | b = [1, 2, 3] 4 | benchmark: 5 | vm1_length: | 6 | a.length 7 | b.length 8 | loop_count: 30000000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_lvar_init.yml: -------------------------------------------------------------------------------- 1 | # while loop cost is not removed because `i` is used in the script 2 | benchmark: 3 | vm1_lvar_init: | 4 | def m v 5 | unless v 6 | # unreachable code 7 | v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 = 8 | v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 = 9 | v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 = 10 | v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 = 11 | v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1 12 | end 13 | end 14 | 15 | i = 0 16 | 17 | while i<30_000_000 18 | i += 1 19 | m i 20 | end 21 | loop_count: 1 22 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_lvar_set.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm1_lvar_set: | 3 | a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1 4 | loop_count: 30000000 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_neq.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | obj1 = Object.new 3 | obj2 = Object.new 4 | benchmark: 5 | vm1_neq: | 6 | obj1 != obj2 7 | loop_count: 30000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_not.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | obj = Object.new 3 | benchmark: 4 | vm1_not: | 5 | !obj 6 | loop_count: 30000000 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_rescue.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm1_rescue: | 3 | begin 4 | rescue 5 | end 6 | loop_count: 30000000 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_simplereturn.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def m 3 | return 1 4 | end 5 | benchmark: 6 | vm1_simplereturn: m 7 | loop_count: 30000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_swap.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | a = 1 3 | b = 2 4 | benchmark: 5 | vm1_swap: | 6 | a, b = b, a 7 | loop_count: 30000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm1_yield.yml: -------------------------------------------------------------------------------- 1 | # while loop cost is not removed due to benchmark_driver.gem's limitation 2 | benchmark: 3 | vm1_yield: | 4 | def m 5 | i = 0 6 | while i<30_000_000 7 | i += 1 8 | yield 9 | end 10 | end 11 | 12 | m{} 13 | loop_count: 1 14 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_array.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm2_array: | 3 | a = [1,2,3,4,5,6,7,8,9,10] 4 | loop_count: 6000000 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_case.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm2_case: | 3 | case :foo 4 | when :bar 5 | raise 6 | when :baz 7 | raise 8 | when :boo 9 | raise 10 | when :foo 11 | # noop 12 | end 13 | loop_count: 6000000 14 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_case_lit.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_case_lit: | 4 | i = 0 5 | @ret = [ "foo", true, false, :sym, 6, nil, 0.1, 0xffffffffffffffff ] 6 | def foo(i) 7 | @ret[i % @ret.size] 8 | end 9 | 10 | while i<6_000_000 11 | case foo(i) 12 | when "foo" then :foo 13 | when true then true 14 | when false then false 15 | when :sym then :sym 16 | when 6 then :fix 17 | when nil then nil 18 | when 0.1 then :float 19 | when 0xffffffffffffffff then :big 20 | end 21 | i += 1 22 | end 23 | loop_count: 1 24 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_defined_method.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class Object 3 | define_method(:m){} 4 | end 5 | benchmark: 6 | vm2_defined_method: | 7 | m; m; m; m; m; m; m; m; 8 | loop_count: 6000000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_dstr.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | x = y = 'z' 3 | benchmark: 4 | vm2_dstr: | 5 | str = "foo#{x}bar#{y}baz" 6 | loop_count: 6000000 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_eval.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm2_eval: | 3 | eval("1") 4 | loop_count: 6000000 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_fiber_allocate.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | # Disable GC to see raw throughput: 3 | GC.disable 4 | benchmark: 5 | vm2_fiber_allocate: | 6 | fiber = Fiber.new{Fiber.yield} 7 | fiber.resume 8 | loop_count: 100000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_fiber_count.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | fibers = [] 3 | benchmark: 4 | vm2_fiber_count: | 5 | fiber = Fiber.new{Fiber.yield} 6 | fibers << fiber 7 | fiber.resume 8 | loop_count: 100000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_fiber_reuse.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | GC.disable 3 | fibers = [] 4 | benchmark: 5 | vm2_fiber_reuse: | 6 | 1024.times do 7 | fiber = Fiber.new{Fiber.yield} 8 | fibers << fiber 9 | fiber.resume 10 | end 11 | 12 | fibers.clear 13 | GC.start 14 | loop_count: 200 15 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_fiber_reuse_gc.yml: -------------------------------------------------------------------------------- 1 | # https://bugs.ruby-lang.org/issues/16009 2 | prelude: | 3 | fibers = [] 4 | benchmark: 5 | vm2_fiber_reuse_gc: | 6 | 2000.times do 7 | fiber = Fiber.new{Fiber.yield} 8 | fibers << fiber 9 | fiber.resume 10 | end 11 | fibers.clear 12 | loop_count: 100 13 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_fiber_switch.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | # based on benchmark for [ruby-core:65518] [Feature #10341] by Knut Franke 3 | fib = Fiber.new do 4 | loop { Fiber.yield } 5 | end 6 | benchmark: 7 | vm2_fiber_switch: | 8 | fib.resume 9 | loop_count: 6000000 10 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_freezestring.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class String 3 | def freeze 4 | -self 5 | end 6 | end 7 | benchmark: 8 | vm2_freezestring: | 9 | "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze 10 | loop_count: 6000000 11 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_method.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def m 3 | nil 4 | end 5 | benchmark: 6 | vm2_method: | 7 | m; m; m; m; m; m; m; m; 8 | loop_count: 6000000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_method_missing.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class C 3 | def method_missing mid 4 | end 5 | end 6 | 7 | obj = C.new 8 | benchmark: 9 | vm2_method_missing: | 10 | obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; 11 | loop_count: 6000000 12 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_method_with_block.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def m 3 | nil 4 | end 5 | benchmark: 6 | vm2_method_with_block: | 7 | m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{}; 8 | loop_count: 6000000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_module_ann_const_set.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm2_module_ann_const_set: | 3 | Module.new.const_set(:X, Module.new) 4 | loop_count: 6000000 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_module_const_set.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | module M 3 | end 4 | $VERBOSE = nil 5 | benchmark: 6 | vm2_module_const_set: | 7 | M.const_set(:X, Module.new) 8 | loop_count: 6000000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_mutex.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | require 'thread' 3 | 4 | m = Thread::Mutex.new 5 | benchmark: 6 | vm2_mutex: | 7 | m.synchronize{} 8 | loop_count: 6000000 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_newlambda.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm2_newlambda: | 3 | lambda {} 4 | loop_count: 6000000 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_poly_method.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_poly_method: | 4 | class C1 5 | def m 6 | 1 7 | end 8 | end 9 | class C2 10 | def m 11 | 2 12 | end 13 | end 14 | 15 | o1 = C1.new 16 | o2 = C2.new 17 | 18 | i = 0 19 | while i<6_000_000 20 | o = (i % 2 == 0) ? o1 : o2 21 | o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m 22 | i += 1 23 | end 24 | loop_count: 1 25 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_poly_method_ov.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_poly_method_ov: | 4 | class C1 5 | def m 6 | 1 7 | end 8 | end 9 | class C2 10 | def m 11 | 2 12 | end 13 | end 14 | 15 | o1 = C1.new 16 | o2 = C2.new 17 | 18 | i = 0 19 | while i<6_000_000 20 | o = (i % 2 == 0) ? o1 : o2 21 | # o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m 22 | i += 1 23 | end 24 | loop_count: 1 25 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_poly_singleton.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_poly_singleton: | 4 | class C1 5 | def m; 1; end 6 | end 7 | 8 | o1 = C1.new 9 | o2 = C1.new 10 | o2.singleton_class 11 | 12 | i = 0 13 | while i<6_000_000 # benchmark loop 2 14 | o = (i % 2 == 0) ? o1 : o2 15 | o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m 16 | i += 1 17 | end 18 | loop_count: 1 19 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_proc.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def m &b 3 | b 4 | end 5 | 6 | pr = m{ 7 | a = 1 8 | } 9 | benchmark: 10 | vm2_proc: | 11 | pr.call 12 | loop_count: 6000000 13 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_raise1.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def rec n 3 | if n > 0 4 | rec n-1 5 | else 6 | raise 7 | end 8 | end 9 | benchmark: 10 | vm2_raise1: | 11 | begin 12 | rec 1 13 | rescue 14 | # ignore 15 | end 16 | loop_count: 6000000 17 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_raise2.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def rec n 3 | if n > 0 4 | rec n-1 5 | else 6 | raise 7 | end 8 | end 9 | benchmark: 10 | vm2_raise2: | 11 | begin 12 | rec 10 13 | rescue 14 | # ignore 15 | end 16 | loop_count: 6000000 17 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_regexp.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | str = 'xxxhogexxx' 3 | benchmark: 4 | vm2_regexp: | 5 | /hoge/ =~ str 6 | loop_count: 6000000 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_send.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class C 3 | def m 4 | end 5 | end 6 | 7 | o = C.new 8 | benchmark: 9 | vm2_send: | 10 | o.__send__ :m 11 | loop_count: 6000000 12 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_string_literal.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm2_string_literal: | 3 | x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 4 | loop_count: 6000000 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_big_aref_hi.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(*('a'..'z').map { |x| x.to_sym }) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_big_aref_hi: | 6 | x.z # x[25] 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_big_aref_lo.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(*('a'..'z').map { |x| x.to_sym }) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_big_aref_lo: | 6 | x.k # x[10] 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_big_aset.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_struct_big_aset: | 4 | s = Struct.new(*('a'..'z').map { |x| x.to_sym }) 5 | x = s.new 6 | i = 0 7 | while i<6_000_000 8 | i += 1 9 | x.k = i # x[10] = i 10 | end 11 | loop_count: 1 12 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_big_href_hi.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(*('a'..'z').map { |x| x.to_sym }) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_big_href_hi: | 6 | x[:z] 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_big_href_lo.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(*('a'..'z').map { |x| x.to_sym }) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_big_href_lo: | 6 | x[:k] 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_big_hset.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_struct_big_hset: | 4 | s = Struct.new(*('a'..'z').map { |x| x.to_sym }) 5 | x = s.new 6 | i = 0 7 | while i<6_000_000 8 | i += 1 9 | x[:k] = i 10 | end 11 | loop_count: 1 12 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_small_aref.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(:a, :b, :c) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_small_aref: | 6 | x.a 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_small_aset.yml: -------------------------------------------------------------------------------- 1 | # loop_count is not utilized since `i` is involved in the script 2 | benchmark: 3 | vm2_struct_small_aset: | 4 | s = Struct.new(:a, :b, :c) 5 | x = s.new 6 | i = 0 7 | while i<6_000_000 8 | i += 1 9 | x.a = i 10 | end 11 | loop_count: 1 12 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_small_href.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(:a, :b, :c) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_small_href: | 6 | x[:a] 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_struct_small_hset.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | s = Struct.new(:a, :b, :c) 3 | x = s.new 4 | benchmark: 5 | vm2_struct_small_hset: | 6 | x[:a] = 1 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_super.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class C 3 | def m 4 | 1 5 | end 6 | end 7 | 8 | class CC < C 9 | def m 10 | super() 11 | end 12 | end 13 | 14 | obj = CC.new 15 | benchmark: 16 | vm2_super: obj.m 17 | loop_count: 6000000 18 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_unif1.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | def m a, b 3 | end 4 | benchmark: 5 | vm2_unif1: | 6 | m 100, 200 7 | loop_count: 6000000 8 | -------------------------------------------------------------------------------- /ruby/benchmark/vm2_zsuper.yml: -------------------------------------------------------------------------------- 1 | prelude: | 2 | class C 3 | def m a 4 | 1 5 | end 6 | end 7 | 8 | class CC < C 9 | def m a 10 | super 11 | end 12 | end 13 | 14 | obj = CC.new 15 | benchmark: 16 | vm2_zsuper: | 17 | obj.m 10 18 | loop_count: 6000000 19 | -------------------------------------------------------------------------------- /ruby/benchmark/vm3_backtrace.rb: -------------------------------------------------------------------------------- 1 | # get last backtrace 2 | 3 | begin 4 | caller(0, 0) 5 | rescue ArgumentError 6 | alias caller_orig caller 7 | def caller lev, n 8 | caller_orig(lev)[0..n] 9 | end 10 | end 11 | 12 | def rec n 13 | if n < 0 14 | 100_000.times{ 15 | caller(0, 1) 16 | } 17 | else 18 | rec(n-1) 19 | end 20 | end 21 | 22 | rec 50 23 | -------------------------------------------------------------------------------- /ruby/benchmark/vm3_clearmethodcache.rb: -------------------------------------------------------------------------------- 1 | i = 0 2 | while i<200_000 3 | i += 1 4 | 5 | Class.new{ 6 | def m; end 7 | } 8 | end 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm3_gc.rb: -------------------------------------------------------------------------------- 1 | 5000.times do 2 | 100.times do 3 | {"xxxx"=>"yyyy"} 4 | end 5 | GC.start 6 | end 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm3_gc_old_full.rb: -------------------------------------------------------------------------------- 1 | old_object = Array.new(1_000_000){''} 2 | 100.times do 3 | GC.start 4 | end 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm3_gc_old_immediate.rb: -------------------------------------------------------------------------------- 1 | old_object = Array.new(1_000_000){''} 2 | 30_000.times do 3 | GC.start(full_mark: false, immediate_sweep: true) 4 | end 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm3_gc_old_lazy.rb: -------------------------------------------------------------------------------- 1 | old_object = Array.new(1_000_000){''} 2 | 30_000.times do 3 | GC.start(full_mark: false, immediate_sweep: false) 4 | end 5 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_symbol_block_pass.rb: -------------------------------------------------------------------------------- 1 | class C 2 | 1000.times {|i| 3 | eval("def i#{i};end") 4 | } 5 | end 6 | 7 | c = C.new 8 | m = C.instance_methods(false) 9 | 5_000.times do 10 | m.each do |n| 11 | c.tap(&n) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_alive_check.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm_thread_alive_check: | 3 | t = Thread.new{} 4 | while t.alive? 5 | Thread.pass 6 | end 7 | loop_count: 50_000 8 | 9 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_alive_check1.rb: -------------------------------------------------------------------------------- 1 | 5_000.times{ 2 | t = Thread.new{} 3 | while t.alive? 4 | Thread.pass 5 | end 6 | } 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_close.rb: -------------------------------------------------------------------------------- 1 | 1000.times { Thread.new { sleep } } 2 | i = 0 3 | while i<100_000 # benchmark loop 3 4 | i += 1 5 | IO.pipe.each(&:close) 6 | end 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_condvar1.rb: -------------------------------------------------------------------------------- 1 | # two threads, two mutex, two condvar ping-pong 2 | require 'thread' 3 | m1 = Mutex.new 4 | m2 = Mutex.new 5 | cv1 = ConditionVariable.new 6 | cv2 = ConditionVariable.new 7 | max = 100000 8 | i = 0 9 | wait = nil 10 | m2.synchronize do 11 | wait = Thread.new do 12 | m1.synchronize do 13 | m2.synchronize { cv2.signal } 14 | while (i += 1) < max 15 | cv1.wait(m1) 16 | cv2.signal 17 | end 18 | end 19 | end 20 | cv2.wait(m2) 21 | end 22 | m1.synchronize do 23 | while i < max 24 | cv1.signal 25 | cv2.wait(m1) 26 | end 27 | end 28 | wait.join 29 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_condvar2.rb: -------------------------------------------------------------------------------- 1 | # many threads, one mutex, many condvars 2 | require 'thread' 3 | m = Mutex.new 4 | cv1 = ConditionVariable.new 5 | cv2 = ConditionVariable.new 6 | max = 1000 7 | n = 100 8 | waiting = 0 9 | scvs = [] 10 | waiters = n.times.map do |i| 11 | start_cv = ConditionVariable.new 12 | scvs << start_cv 13 | start_mtx = Mutex.new 14 | start_mtx.synchronize do 15 | th = Thread.new(start_mtx, start_cv) do |sm, scv| 16 | m.synchronize do 17 | sm.synchronize { scv.signal } 18 | max.times do 19 | cv2.signal if (waiting += 1) == n 20 | cv1.wait(m) 21 | end 22 | end 23 | end 24 | start_cv.wait(start_mtx) 25 | th 26 | end 27 | end 28 | m.synchronize do 29 | max.times do 30 | cv2.wait(m) until waiting == n 31 | waiting = 0 32 | cv1.broadcast 33 | end 34 | end 35 | waiters.each(&:join) 36 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_create_join.rb: -------------------------------------------------------------------------------- 1 | i = 0 2 | while i<100_000 # benchmark loop 3 3 | i += 1 4 | Thread.new{ 5 | }.join 6 | end 7 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_mutex1.rb: -------------------------------------------------------------------------------- 1 | # one thread, one mutex (no contention) 2 | 3 | require 'thread' 4 | m = Thread::Mutex.new 5 | r = 0 6 | max = 2000 7 | lmax = max * max 8 | (1..1).map{ 9 | Thread.new{ 10 | i = 0 11 | while i 0 14 | q.push true 15 | n -= 1 16 | end 17 | q.push nil 18 | } 19 | 20 | consumer.join 21 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_sized_queue2.rb: -------------------------------------------------------------------------------- 1 | require 'thread' 2 | # one producer, many consumers 3 | n = 1_000_000 4 | m = 10 5 | q = Thread::SizedQueue.new(100) 6 | consumers = m.times.map do 7 | Thread.new do 8 | while q.pop 9 | # consuming 10 | end 11 | end 12 | end 13 | 14 | producer = Thread.new do 15 | while n > 0 16 | q.push true 17 | n -= 1 18 | end 19 | m.times { q.push nil } 20 | end 21 | 22 | producer.join 23 | consumers.each(&:join) 24 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_sized_queue3.rb: -------------------------------------------------------------------------------- 1 | require 'thread' 2 | # many producers, one consumer 3 | n = 1_000_000 4 | m = 10 5 | q = Thread::SizedQueue.new(100) 6 | consumer = Thread.new do 7 | while q.pop 8 | # consuming 9 | end 10 | end 11 | 12 | producers = m.times.map do 13 | Thread.new do 14 | while n > 0 15 | q.push true 16 | n -= 1 17 | end 18 | end 19 | end 20 | producers.each(&:join) 21 | q.push nil 22 | consumer.join 23 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_sized_queue4.rb: -------------------------------------------------------------------------------- 1 | require 'thread' 2 | # many producers, many consumers 3 | nr = 1_000_000 4 | n = 10 5 | m = 10 6 | q = Thread::SizedQueue.new(100) 7 | consumers = n.times.map do 8 | Thread.new do 9 | while q.pop 10 | # consuming 11 | end 12 | end 13 | end 14 | 15 | producers = m.times.map do 16 | Thread.new do 17 | while nr > 0 18 | q.push true 19 | nr -= 1 20 | end 21 | end 22 | end 23 | 24 | producers.each(&:join) 25 | n.times { q.push nil } 26 | consumers.each(&:join) 27 | -------------------------------------------------------------------------------- /ruby/benchmark/vm_thread_sleep.yml: -------------------------------------------------------------------------------- 1 | benchmark: 2 | vm_thread_sleep: | 3 | Thread.new { sleep } 4 | loop_count: 10_000 5 | -------------------------------------------------------------------------------- /ruby/driver.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'digest' 4 | require 'optparse' 5 | require 'shellwords' 6 | 7 | opt = { pattern: [], runner: 'seconds' } 8 | 9 | OptionParser.new{|o| 10 | o.on('-r', '--runner RUNNER', String, "Runner (default: seconds)"){|r| 11 | opt[:runner] = r 12 | } 13 | o.on('-e', '--executables [EXEC]', "Specify benchmark target (e1::path1)"){|e| 14 | opt[:exec] = e # discard... 15 | } 16 | o.on('-p', '--pattern ', "Benchmark name pattern"){|p| 17 | opt[:pattern] = p.split(',') 18 | } 19 | o.on('--with-jit', "Run benchmarks once with JIT enabled and once without"){ 20 | opt[:jit] = true 21 | } 22 | o.on('--repeat-count [NUM]', "Repeat count"){|n| 23 | opt[:repeat] = n.to_i 24 | } 25 | o.on('-o', '--output-file [FILE]', "Output file"){|f| 26 | opt[:output] = f # discard... 27 | } 28 | }.parse!(ARGV) 29 | 30 | filter = opt.fetch(:pattern).map { |p| ['--filter', p] }.flatten 31 | 32 | benchmark_dir = File.expand_path('./benchmark', __dir__) 33 | benchmarks = Dir.glob("#{benchmark_dir}/*.rb") + Dir.glob("#{benchmark_dir}/*.yml") 34 | 35 | benchmarks.sort.each do |benchmark| 36 | if opt[:runner] == 'rsskb' 37 | name = 'rss_kb' 38 | else 39 | name = File.basename(benchmark).sub(/\.[^.]+\z/, '') 40 | end 41 | execs = ['-e', "#{name}::#{RbConfig.ruby.shellescape}"] 42 | if opt[:jit] 43 | execs += ['-e', "#{name}_jit::#{RbConfig.ruby.shellescape} --jit"] 44 | end 45 | 46 | ENV['REPO_NAME'] = 'ruby' 47 | ENV['ORGANIZATION_NAME'] = 'ruby' 48 | ENV['BENCHMARK_TYPE_DIGEST'] = Digest::SHA2.file("#{File.dirname(__FILE__)}/benchmark/#{File.basename(benchmark)}").hexdigest 49 | ENV['BENCHMARK_TYPE_SCRIPT_URL'] = "https://raw.githubusercontent.com/ruby-bench/ruby-bench-suite/master/ruby/benchmark/#{File.basename(benchmark)}" 50 | ENV['RUBY_ENVIRONMENT'] = 'true' 51 | ENV['LANG'] = 'C.UTF-8' # avoid invalid byte sequence 52 | 53 | command = [ 54 | 'benchmark-driver', benchmark, *execs, *filter, 55 | '--runner', opt[:runner], '--output', 'rubybench', 56 | '--repeat-count', opt[:repeat].to_s, 57 | '--repeat-result', 'best', 58 | '--timeout', '60', 59 | ] 60 | 61 | puts "+ #{command.shelljoin}" 62 | unless system(command.shelljoin) 63 | abort "Failed to execute: #{command.shelljoin}" 64 | end 65 | puts 66 | end 67 | -------------------------------------------------------------------------------- /sequel/.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_PATH: "vendor/bundle" 3 | BUNDLE_DISABLE_SHARED_GEMS: "true" 4 | -------------------------------------------------------------------------------- /sequel/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | module ::Kernel 4 | def sequel_master? 5 | ENV["SEQUEL_MASTER"] == '1' 6 | end 7 | 8 | def mysql2_prepared_statements? 9 | ENV["MYSQL2_PREPARED_STATEMENTS"] == '1' 10 | end 11 | end 12 | 13 | if sequel_master? 14 | gem 'sequel', github: 'jeremyevans/sequel', branch: 'master' 15 | else 16 | gem 'sequel', path: '/sequel' 17 | end 18 | 19 | gem 'sequel_pg', require: 'sequel' 20 | gem 'activemodel', '~> 4.2.6' 21 | 22 | if mysql2_prepared_statements? 23 | gem 'mysql2', '0.4.2' 24 | else 25 | gem 'mysql2', '0.3.18' 26 | end 27 | 28 | gem 'pg', '0.18.1' 29 | gem 'benchmark-ips', '~> 2.2.0' 30 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_create_string_columns.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_create_string_columns_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model 10 | self.raise_on_save_failure = true 11 | plugin :timestamps, update_on_create: true 12 | end 13 | 14 | attributes = {} 15 | 16 | 25.times do |i| 17 | attributes[:"column#{i}"] = "Some string #{i}" 18 | end 19 | 20 | Benchmark.sequel("sequel/#{db_adapter}_create_string_columns", time: 5) do 21 | User.create(attributes) 22 | end 23 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_destroy.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_destroy_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model 10 | self.raise_on_save_failure = true 11 | plugin :timestamps, update_on_create: true 12 | end 13 | 14 | attributes = { 15 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 16 | email: "foobar@email.com" 17 | } 18 | 19 | Benchmark.sequel("sequel/#{db_adapter}_destroy", time: 5) do 20 | # we need to create the record in order to delete it 21 | user = User.create(attributes) 22 | user.destroy 23 | end 24 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_discourse.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "sequel" 3 | 4 | require_relative "support/benchmark_sequel" 5 | 6 | db_setup script: "bm_discourse_setup.rb" 7 | 8 | DB = Sequel.connect(ENV.fetch("DATABASE_URL")) 9 | 10 | class User < Sequel::Model 11 | one_to_many :topic_users 12 | one_to_many :category_users 13 | one_to_many :topics 14 | end 15 | 16 | class Topic < Sequel::Model 17 | one_to_many :topic_users 18 | one_to_many :categories 19 | many_to_one :user 20 | many_to_one :category 21 | 22 | dataset_module do 23 | def listable_topics 24 | where(Sequel.lit("topics.archetype <> ?", "private_message")) 25 | end 26 | end 27 | end 28 | 29 | class TopicUser < Sequel::Model 30 | many_to_one :topic 31 | many_to_one :user 32 | end 33 | 34 | class Category < Sequel::Model 35 | one_to_many :category_users 36 | one_to_many :topics 37 | many_to_one :topic 38 | end 39 | 40 | class CategoryUser < Sequel::Model 41 | many_to_one :category 42 | many_to_one :user 43 | end 44 | 45 | user = User.first 46 | 47 | Benchmark.sequel("sequel/#{db_adapter}_discourse", time: 5) do 48 | str = "" 49 | Topic 50 | .unfiltered 51 | .eager_graph(Sequel.as(:category, :categories)) 52 | .eager(:user) 53 | .left_outer_join(Sequel.lit("topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{user.id})")) 54 | .listable_topics 55 | .where(Sequel.lit("COALESCE(categories.topic_id, 0) <> topics.id")) 56 | .where(Sequel.lit("topics.deleted_at IS NULL")) 57 | .where(Sequel.lit( 58 | "NOT EXISTS ( 59 | SELECT 1 FROM category_users cu 60 | WHERE cu.user_id = :user_id 61 | AND cu.category_id = topics.category_id 62 | AND cu.notification_level = :muted 63 | AND cu.category_id <> :category_id 64 | AND (tu.notification_level IS NULL OR tu.notification_level < :tracking) 65 | )", 66 | user_id: user.id, muted: 0, tracking: 2, category_id: -1) 67 | ).where( 68 | Sequel.lit( 69 | "pinned_globally AND 70 | pinned_at IS NOT NULL AND 71 | (topics.pinned_at > tu.cleared_pinned_at OR tu.cleared_pinned_at IS NULL)" 72 | ) 73 | ).order(Sequel.lit("topics.bumped_at DESC")) 74 | .limit(30) 75 | .all 76 | .each do |topic| 77 | str << "id: #{topic.id} title: #{topic.title} created_at: #{topic.created_at.iso8601} user: #{topic.user.username}\n" 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_finders_find_by_attributes.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_finders_find_by_attributes", time: 5) do 12 | user = User.select(:name, :email)[email: 'shatrov@me.com'] 13 | str = "name: #{user.name} email: #{user.email}" 14 | end 15 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_finders_find_by_attributes_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_finders_find_by_attributes_over_select", time: 5) do 12 | user = User.find(email: 'shatrov@me.com') 13 | str = "name: #{user.name} email: #{user.email}" 14 | end 15 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_finders_first.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_finders_first", time: 5) do 12 | user = User.select(:name, :email).first 13 | str = "name: #{user.name} email: #{user.email}" 14 | end 15 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_finders_first_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_finders_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_finders_first_over_select", time: 5) do 12 | user = User.first 13 | str = "name: #{user.name} email: #{user.email}" 14 | end 15 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_save.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_save_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model 10 | self.raise_on_save_failure = true 11 | plugin :timestamps, update_on_create: true 12 | end 13 | 14 | attributes = { 15 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 16 | email: "foobar@email.com" 17 | } 18 | 19 | Benchmark.sequel("sequel/#{db_adapter}_save", time: 5) do 20 | user = User.new(attributes) 21 | user.save 22 | end 23 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_scope_all.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_scope_all_setup.rb" 6 | 7 | Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_scope_all", time: 5) do 12 | str = "" 13 | User.select(:name, :email, :approved, :age, :birthday).each do |user| 14 | str << "name: #{user.name} email: #{user.email} approved: #{user.approved} age: #{user.age} birthday: #{user.birthday}\n" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_scope_all_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_scope_all_setup.rb" 6 | 7 | Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_scope_all_over_select", time: 5) do 12 | str = "" 13 | User.all.each do |user| 14 | str << "name: #{user.name} email: #{user.email} approved: #{user.approved} age: #{user.age} birthday: #{user.birthday}\n" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_scope_all_with_default_scope.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_with_default_scope_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model 10 | dataset_module do 11 | def only_admins 12 | where(:admin => true) 13 | end 14 | end 15 | 16 | set_dataset(self.only_admins) 17 | end 18 | 19 | Benchmark.sequel("sequel/#{db_adapter}_scope_all_with_default_scope", time: 5) do 20 | str = "" 21 | User.select(:name, :email).each do |user| 22 | str << "name: #{user.name} email: #{user.email}\n" 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_scope_all_with_default_scope_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_with_default_scope_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model 10 | dataset_module do 11 | def only_admins 12 | where(:admin => true) 13 | end 14 | end 15 | 16 | set_dataset(self.only_admins) 17 | end 18 | 19 | Benchmark.sequel("sequel/#{db_adapter}_scope_all_with_default_scope_over_select", time: 5) do 20 | str = "" 21 | User.all.each do |user| 22 | str << "name: #{user.name} email: #{user.email}\n" 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_scope_where.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_scope_where_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_scope_where", time: 5) do 12 | str = "" 13 | User 14 | .select(:name, :email) 15 | .where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") 16 | .where(Sequel.lit('email LIKE ?', 'foobar00%@email.com')) 17 | .each { |user| str << "name: #{user.name} email: #{user.email}\n" } 18 | end 19 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_scope_where_over_select.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_scope_where_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class User < Sequel::Model; end 10 | 11 | Benchmark.sequel("sequel/#{db_adapter}_scope_where_over_select", time: 5) do 12 | str = "" 13 | User 14 | .where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") 15 | .where(Sequel.lit('email LIKE ?', 'foobar00%@email.com')) 16 | .each { |user| str << "name: #{user.name} email: #{user.email}\n" } 17 | end 18 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_validations_invalid.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_validations_invalid_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class Post < Sequel::Model 10 | plugin :validation_helpers 11 | def validate 12 | super 13 | validates_presence :title 14 | validates_unique :sequence 15 | validates_numeric :age, numericality: { greater_than: 18, less_than: 80 } 16 | validates_format /\A[a-zA-Z]+\z/, :legacy_code, message: "only allows letters" 17 | validates_includes %w(small medium large), :size, message: "%{value} is not a valid size" 18 | end 19 | end 20 | 21 | post = Post.new({ 22 | title: '', 23 | author: '', 24 | age: 10, 25 | sequence: 90, 26 | legacy_code: '32_leg', 27 | size: 'overbig' 28 | }) 29 | 30 | Benchmark.sequel("sequel/#{db_adapter}_validations_invalid", time: 5) do 31 | if post.valid? 32 | raise "should not be valid" 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /sequel/benchmarks/bm_sequel_validations_valid.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'sequel' 3 | require_relative 'support/benchmark_sequel' 4 | 5 | db_setup script: "bm_validations_valid_setup.rb" 6 | 7 | DB = Sequel.connect(ENV.fetch('DATABASE_URL')) 8 | 9 | class Post < Sequel::Model 10 | plugin :validation_helpers 11 | def validate 12 | super 13 | validates_presence :title 14 | validates_unique :sequence 15 | validates_numeric :age, numericality: { greater_than: 18, less_than: 80 } 16 | validates_format /\A[a-zA-Z]+\z/, :legacy_code, message: "only allows letters" 17 | validates_includes %w(small medium large), :size, message: "%{value} is not a valid size" 18 | end 19 | end 20 | 21 | post = Post.new({ 22 | title: 'RubyBench', 23 | author: 'RubyBench', 24 | age: 21, 25 | sequence: 90, 26 | legacy_code: 'letters', 27 | size: 'small' 28 | }) 29 | 30 | Benchmark.sequel("sequel/#{db_adapter}_validations_valid", time: 5) do 31 | if post.valid? 32 | raise "should be valid" 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /sequel/benchmarks/support/benchmark_sequel.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../../support/benchmark_runner' 2 | require_relative '../../../support/helpers' 3 | 4 | module Benchmark 5 | module Sequel 6 | def sequel(label=nil, version: ::Sequel.version.to_s, time:, disable_gc: true, warmup: 3, &block) 7 | Benchmark::Runner.run(label, version: version, time: time, disable_gc: disable_gc, warmup: warmup, &block) 8 | end 9 | end 10 | 11 | extend Benchmark::Sequel 12 | end 13 | -------------------------------------------------------------------------------- /suite-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruby-bench/ruby-bench-suite/049ed0e898a4dfb06945ac63fb56457c094eeffa/suite-logo.png -------------------------------------------------------------------------------- /support/benchmark_runner.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark/ips' 2 | require 'json' 3 | 4 | module Benchmark 5 | module Runner 6 | def self.run(label=nil, version:, time:, disable_gc:, warmup:, &block) 7 | unless block_given? 8 | raise ArgumentError.new, "You must pass block to run" 9 | end 10 | 11 | GC.disable if disable_gc 12 | 13 | ips_result = compute_ips(time, warmup, label, &block) 14 | objects_result = compute_objects(&block) 15 | 16 | print_output(ips_result, objects_result, label, version) 17 | end 18 | 19 | def self.compute_ips(time, warmup, label, &block) 20 | report = Benchmark.ips(time, warmup, true) do |x| 21 | x.report(label) { yield } 22 | end 23 | 24 | report.entries.first 25 | end 26 | 27 | def self.compute_objects(&block) 28 | if block_given? 29 | key = 30 | if RUBY_VERSION < '2.2' 31 | :total_allocated_object 32 | else 33 | :total_allocated_objects 34 | end 35 | 36 | before = GC.stat[key] 37 | yield 38 | after = GC.stat[key] 39 | after - before 40 | end 41 | end 42 | 43 | def self.print_output(ips_result, objects_result, label, version) 44 | standard_deviation = 45 | # https://github.com/evanphx/benchmark-ips/commit/b42c3dfbe104f32ce7db075a01858d598da87a8b 46 | if ips_result.respond_to?(:error_percentage) 47 | ips_result.error_percentage 48 | else 49 | ips_result.stddev_percentage # deprecated 50 | end 51 | output = { 52 | label: label, 53 | version: version, 54 | iterations_per_second: ips_result.ips, 55 | iterations_per_second_standard_deviation: standard_deviation, 56 | total_allocated_objects_per_iteration: objects_result, 57 | }.to_json 58 | 59 | puts output 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /support/helpers.rb: -------------------------------------------------------------------------------- 1 | STRING_COLUMNS_COUNT = 25 2 | 3 | def db_adapter 4 | ENV['DATABASE_URL'].split(":")[0] 5 | end 6 | 7 | def db_setup(script:) 8 | Dir.chdir("../../support/setup") do 9 | `DATABASE_URL=#{ENV.fetch("DATABASE_URL")} BUNDLE_GEMFILE=Gemfile ruby #{script}` 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /support/setup/.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_DISABLE_SHARED_GEMS: "true" 3 | BUNDLE_PATH: "vendor/bundle" 4 | BUNDLE_JOBS: "4" 5 | -------------------------------------------------------------------------------- /support/setup/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | group :postgres do 4 | gem "pg" 5 | end 6 | 7 | group :mysql do 8 | gem "mysql2" 9 | end 10 | 11 | gem "activerecord" 12 | -------------------------------------------------------------------------------- /support/setup/bm_create_string_columns_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | require_relative "../helpers" 4 | 5 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 6 | ActiveRecord::Migration.verbose = false 7 | 8 | ActiveRecord::Schema.define do 9 | create_table :users, force: true do |t| 10 | STRING_COLUMNS_COUNT.times do |i| 11 | t.string :"column#{i}" 12 | end 13 | 14 | t.timestamps null: false 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /support/setup/bm_destroy_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :users, force: true do |t| 9 | t.string :name, :email 10 | t.timestamps null: false 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /support/setup/bm_finders_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :users, force: true do |t| 9 | t.string :name 10 | t.string :email 11 | t.boolean :approved 12 | t.integer :age 13 | t.datetime :birthday 14 | t.timestamps null: false 15 | end 16 | end 17 | 18 | class User < ActiveRecord::Base; end 19 | 20 | attributes = { 21 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 22 | email: "foobar@email.com", 23 | approved: false, 24 | age: 51, 25 | birthday: DateTime.now 26 | } 27 | 28 | 1000.times do 29 | User.create!(attributes) 30 | end 31 | 32 | User.create!( 33 | name: 'kir', 34 | email: 'shatrov@me.com', 35 | approved: true, 36 | birthday: DateTime.now 37 | ) 38 | -------------------------------------------------------------------------------- /support/setup/bm_preload_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :users, force: true do |t| 9 | t.string :name, :email 10 | t.integer :topic_id 11 | t.timestamps null: false 12 | end 13 | 14 | create_table :topics, force: true do |t| 15 | t.string :title 16 | t.timestamps null: false 17 | end 18 | end 19 | 20 | attributes = { 21 | name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 22 | email: 'foobar@email.com' 23 | } 24 | 25 | class Topic < ActiveRecord::Base 26 | has_many :users 27 | end 28 | 29 | class User < ActiveRecord::Base 30 | belongs_to :topic 31 | end 32 | 33 | 100.times do 34 | User.create!(attributes) 35 | end 36 | 37 | users = User.first(50) 38 | 39 | 100.times do 40 | Topic.create!(title: 'This is a topic', users: users) 41 | end 42 | -------------------------------------------------------------------------------- /support/setup/bm_save_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :users, force: true do |t| 9 | t.string :name, :email 10 | t.timestamps null: false 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /support/setup/bm_scope_all_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | 6 | ActiveRecord::Migration.verbose = false 7 | 8 | ActiveRecord::Schema.define do 9 | create_table :users, force: true do |t| 10 | t.string :name 11 | t.string :email 12 | t.boolean :approved 13 | t.integer :age 14 | t.datetime :birthday 15 | t.timestamps null: false 16 | end 17 | end 18 | 19 | class User < ActiveRecord::Base; end 20 | 21 | attributes = { 22 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 23 | email: "foobar@email.com", 24 | approved: false, 25 | age: 51, 26 | birthday: DateTime.now 27 | } 28 | 29 | 1000.times do 30 | User.create!(attributes) 31 | end 32 | 33 | -------------------------------------------------------------------------------- /support/setup/bm_scope_where_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :users, force: true do |t| 9 | t.string :name 10 | t.string :email 11 | t.boolean :approved 12 | t.integer :age 13 | t.datetime :birthday 14 | t.timestamps null: false 15 | end 16 | 17 | add_index :users, :email, unique: true 18 | end 19 | 20 | class User < ActiveRecord::Base; end 21 | 22 | 1000.times do |i| 23 | User.create!({ 24 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 25 | email: "foobar#{"%03d" % i}@email.com", 26 | approved: false, 27 | age: 51, 28 | birthday: DateTime.now 29 | }) 30 | end 31 | -------------------------------------------------------------------------------- /support/setup/bm_validations_invalid_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :posts, force: true do |t| 9 | t.string :title 10 | t.string :author 11 | t.text :body 12 | t.integer :sequence 13 | t.integer :age 14 | t.string :subdomain 15 | t.string :legacy_code 16 | t.string :size 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /support/setup/bm_validations_valid_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :posts, force: true do |t| 9 | t.string :title 10 | t.string :author 11 | t.text :body 12 | t.integer :sequence 13 | t.integer :age 14 | t.string :subdomain 15 | t.string :legacy_code 16 | t.string :size 17 | end 18 | end 19 | 20 | class Post < ActiveRecord::Base; end 21 | 22 | Post.create!({ 23 | title: 'RubyBench', 24 | author: 'RubyBench', 25 | age: 21, 26 | sequence: 90, 27 | subdomain: 'ru', 28 | legacy_code: 'letters', 29 | size: 'small' 30 | }) 31 | -------------------------------------------------------------------------------- /support/setup/bm_with_default_scope_setup.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "active_record" 3 | 4 | ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) 5 | ActiveRecord::Migration.verbose = false 6 | 7 | ActiveRecord::Schema.define do 8 | create_table :users, force: true do |t| 9 | t.string :name 10 | t.string :email 11 | t.boolean :approved 12 | t.integer :age 13 | t.datetime :birthday 14 | t.boolean :admin 15 | t.timestamps null: false 16 | end 17 | end 18 | 19 | class User < ActiveRecord::Base; end 20 | 21 | attributes = { 22 | name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 23 | email: "foobar@email.com", 24 | approved: false, 25 | age: 51 26 | } 27 | 28 | 500.times { User.create!(attributes.merge(admin: true)) } 29 | 500.times { User.create!(attributes.merge(admin: false)) } 30 | --------------------------------------------------------------------------------