mini_sql 1.0 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.github/workflows/ci.yml +1 -1
 - data/CHANGELOG +20 -0
 - data/README.md +36 -0
 - data/bench/builder_perf.rb +138 -0
 - data/bench/decorator_perf.rb +143 -0
 - data/bench/mini_sql_methods_perf.rb +80 -0
 - data/bench/prepared_perf.rb +59 -0
 - data/bench/shared/generate_data.rb +133 -0
 - data/bench/topic_perf.rb +21 -327
 - data/bench/topic_wide_perf.rb +92 -0
 - data/lib/mini_sql.rb +17 -8
 - data/lib/mini_sql/abstract/prepared_binds.rb +74 -0
 - data/lib/mini_sql/abstract/prepared_cache.rb +45 -0
 - data/lib/mini_sql/builder.rb +63 -30
 - data/lib/mini_sql/inline_param_encoder.rb +4 -5
 - data/lib/mini_sql/mysql/connection.rb +13 -3
 - data/lib/mini_sql/mysql/deserializer_cache.rb +3 -3
 - data/lib/mini_sql/mysql/prepared_binds.rb +15 -0
 - data/lib/mini_sql/mysql/prepared_cache.rb +21 -0
 - data/lib/mini_sql/mysql/prepared_connection.rb +47 -0
 - data/lib/mini_sql/postgres/connection.rb +21 -7
 - data/lib/mini_sql/postgres/deserializer_cache.rb +5 -5
 - data/lib/mini_sql/postgres/prepared_binds.rb +15 -0
 - data/lib/mini_sql/postgres/prepared_cache.rb +25 -0
 - data/lib/mini_sql/postgres/prepared_connection.rb +39 -0
 - data/lib/mini_sql/postgres_jdbc/connection.rb +3 -1
 - data/lib/mini_sql/postgres_jdbc/deserializer_cache.rb +3 -3
 - data/lib/mini_sql/result.rb +10 -0
 - data/lib/mini_sql/serializer.rb +29 -15
 - data/lib/mini_sql/sqlite/connection.rb +14 -2
 - data/lib/mini_sql/sqlite/deserializer_cache.rb +3 -3
 - data/lib/mini_sql/sqlite/prepared_binds.rb +15 -0
 - data/lib/mini_sql/sqlite/prepared_cache.rb +21 -0
 - data/lib/mini_sql/sqlite/prepared_connection.rb +43 -0
 - data/lib/mini_sql/version.rb +1 -1
 - metadata +20 -3
 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'bundler/inline'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            gemfile do
         
     | 
| 
      
 6 
     | 
    
         
            +
              source 'https://rubygems.org'
         
     | 
| 
      
 7 
     | 
    
         
            +
              gem 'mini_sql', path: '../'
         
     | 
| 
      
 8 
     | 
    
         
            +
              gem 'pg'
         
     | 
| 
      
 9 
     | 
    
         
            +
              gem 'activerecord'
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem 'activemodel'
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem 'benchmark-ips'
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require 'benchmark/ips'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'mini_sql'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            require '../mini_sql/bench/shared/generate_data'
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            ar_connection, _ = GenerateData.new(count_records: 10_000).call
         
     | 
| 
      
 21 
     | 
    
         
            +
            MINI_SQL = MiniSql::Connection.get(ar_connection.raw_connection)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            sql = <<~SQL
         
     | 
| 
      
 25 
     | 
    
         
            +
              select users.first_name, count(distinct topics.id) topics_count
         
     | 
| 
      
 26 
     | 
    
         
            +
              from topics
         
     | 
| 
      
 27 
     | 
    
         
            +
              inner join users on user_id = users.id
         
     | 
| 
      
 28 
     | 
    
         
            +
              inner join categories on category_id = categories.id
         
     | 
| 
      
 29 
     | 
    
         
            +
              where users.id = ?
         
     | 
| 
      
 30 
     | 
    
         
            +
              group by users.id
         
     | 
| 
      
 31 
     | 
    
         
            +
            SQL
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            Benchmark.ips do |x|
         
     | 
| 
      
 34 
     | 
    
         
            +
              x.report("ps") do |n|
         
     | 
| 
      
 35 
     | 
    
         
            +
                while n > 0
         
     | 
| 
      
 36 
     | 
    
         
            +
                  MINI_SQL.prepared.query(sql, rand(100))
         
     | 
| 
      
 37 
     | 
    
         
            +
                  n -= 1
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
              x.report("without ps") do |n|
         
     | 
| 
      
 41 
     | 
    
         
            +
                while n > 0
         
     | 
| 
      
 42 
     | 
    
         
            +
                  MINI_SQL.query(sql, rand(100))
         
     | 
| 
      
 43 
     | 
    
         
            +
                  n -= 1
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              x.compare!
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            # Warming up --------------------------------------
         
     | 
| 
      
 51 
     | 
    
         
            +
            #                   ps     1.008k i/100ms
         
     | 
| 
      
 52 
     | 
    
         
            +
            #           without ps   284.000  i/100ms
         
     | 
| 
      
 53 
     | 
    
         
            +
            # Calculating -------------------------------------
         
     | 
| 
      
 54 
     | 
    
         
            +
            #                   ps     10.287k (± 4.2%) i/s -     51.408k in   5.006807s
         
     | 
| 
      
 55 
     | 
    
         
            +
            #           without ps      2.970k (± 5.3%) i/s -     15.052k in   5.083272s
         
     | 
| 
      
 56 
     | 
    
         
            +
            #
         
     | 
| 
      
 57 
     | 
    
         
            +
            # Comparison:
         
     | 
| 
      
 58 
     | 
    
         
            +
            #                   ps:    10287.2 i/s
         
     | 
| 
      
 59 
     | 
    
         
            +
            #           without ps:     2970.0 i/s - 3.46x  (± 0.00) slower
         
     | 
| 
         @@ -0,0 +1,133 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class GenerateData
         
     | 
| 
      
 4 
     | 
    
         
            +
              class ::Topic < ActiveRecord::Base;
         
     | 
| 
      
 5 
     | 
    
         
            +
                belongs_to :user
         
     | 
| 
      
 6 
     | 
    
         
            +
                belongs_to :category
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
              class ::User < ActiveRecord::Base; end
         
     | 
| 
      
 9 
     | 
    
         
            +
              class ::Category < ActiveRecord::Base; end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def initialize(count_records:)
         
     | 
| 
      
 12 
     | 
    
         
            +
                @count_records = count_records
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def call
         
     | 
| 
      
 16 
     | 
    
         
            +
                conn_settings = {
         
     | 
| 
      
 17 
     | 
    
         
            +
                  password: 'postgres',
         
     | 
| 
      
 18 
     | 
    
         
            +
                  user: 'postgres',
         
     | 
| 
      
 19 
     | 
    
         
            +
                  host: 'localhost'
         
     | 
| 
      
 20 
     | 
    
         
            +
                }
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                db_conn = conn_settings.merge(database: "test_db", adapter: "postgresql")
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                pg = PG::Connection.new(conn_settings)
         
     | 
| 
      
 25 
     | 
    
         
            +
                pg.exec "DROP DATABASE IF EXISTS test_db"
         
     | 
| 
      
 26 
     | 
    
         
            +
                pg.exec "CREATE DATABASE test_db"
         
     | 
| 
      
 27 
     | 
    
         
            +
                pg.close
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                ActiveRecord::Base.establish_connection(db_conn)
         
     | 
| 
      
 30 
     | 
    
         
            +
                pg = ActiveRecord::Base.connection.raw_connection
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                pg.exec <<~SQL
         
     | 
| 
      
 33 
     | 
    
         
            +
                  drop table if exists topics;
         
     | 
| 
      
 34 
     | 
    
         
            +
                  drop table if exists users;
         
     | 
| 
      
 35 
     | 
    
         
            +
                  drop table if exists categories;
         
     | 
| 
      
 36 
     | 
    
         
            +
                  CREATE TABLE topics (
         
     | 
| 
      
 37 
     | 
    
         
            +
                    id integer NOT NULL PRIMARY KEY,
         
     | 
| 
      
 38 
     | 
    
         
            +
                    title character varying NOT NULL,
         
     | 
| 
      
 39 
     | 
    
         
            +
                    last_posted_at timestamp without time zone,
         
     | 
| 
      
 40 
     | 
    
         
            +
                    created_at timestamp without time zone NOT NULL,
         
     | 
| 
      
 41 
     | 
    
         
            +
                    updated_at timestamp without time zone NOT NULL,
         
     | 
| 
      
 42 
     | 
    
         
            +
                    views integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 43 
     | 
    
         
            +
                    posts_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    user_id integer,
         
     | 
| 
      
 45 
     | 
    
         
            +
                    last_post_user_id integer NOT NULL,
         
     | 
| 
      
 46 
     | 
    
         
            +
                    reply_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 47 
     | 
    
         
            +
                    featured_user1_id integer,
         
     | 
| 
      
 48 
     | 
    
         
            +
                    featured_user2_id integer,
         
     | 
| 
      
 49 
     | 
    
         
            +
                    featured_user3_id integer,
         
     | 
| 
      
 50 
     | 
    
         
            +
                    avg_time integer,
         
     | 
| 
      
 51 
     | 
    
         
            +
                    deleted_at timestamp without time zone,
         
     | 
| 
      
 52 
     | 
    
         
            +
                    highest_post_number integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 53 
     | 
    
         
            +
                    image_url character varying,
         
     | 
| 
      
 54 
     | 
    
         
            +
                    like_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 55 
     | 
    
         
            +
                    incoming_link_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 56 
     | 
    
         
            +
                    category_id integer,
         
     | 
| 
      
 57 
     | 
    
         
            +
                    visible boolean DEFAULT true NOT NULL,
         
     | 
| 
      
 58 
     | 
    
         
            +
                    moderator_posts_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 59 
     | 
    
         
            +
                    closed boolean DEFAULT false NOT NULL,
         
     | 
| 
      
 60 
     | 
    
         
            +
                    archived boolean DEFAULT false NOT NULL,
         
     | 
| 
      
 61 
     | 
    
         
            +
                    bumped_at timestamp without time zone NOT NULL,
         
     | 
| 
      
 62 
     | 
    
         
            +
                    has_summary boolean DEFAULT false NOT NULL,
         
     | 
| 
      
 63 
     | 
    
         
            +
                    vote_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 64 
     | 
    
         
            +
                    archetype character varying DEFAULT 'regular'::character varying NOT NULL,
         
     | 
| 
      
 65 
     | 
    
         
            +
                    featured_user4_id integer,
         
     | 
| 
      
 66 
     | 
    
         
            +
                    notify_moderators_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    spam_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 68 
     | 
    
         
            +
                    pinned_at timestamp without time zone,
         
     | 
| 
      
 69 
     | 
    
         
            +
                    score double precision,
         
     | 
| 
      
 70 
     | 
    
         
            +
                    percent_rank double precision DEFAULT 1.0 NOT NULL,
         
     | 
| 
      
 71 
     | 
    
         
            +
                    subtype character varying,
         
     | 
| 
      
 72 
     | 
    
         
            +
                    slug character varying,
         
     | 
| 
      
 73 
     | 
    
         
            +
                    deleted_by_id integer,
         
     | 
| 
      
 74 
     | 
    
         
            +
                    participant_count integer DEFAULT 1,
         
     | 
| 
      
 75 
     | 
    
         
            +
                    word_count integer,
         
     | 
| 
      
 76 
     | 
    
         
            +
                    excerpt character varying(1000),
         
     | 
| 
      
 77 
     | 
    
         
            +
                    pinned_globally boolean DEFAULT false NOT NULL,
         
     | 
| 
      
 78 
     | 
    
         
            +
                    pinned_until timestamp without time zone,
         
     | 
| 
      
 79 
     | 
    
         
            +
                    fancy_title character varying(400),
         
     | 
| 
      
 80 
     | 
    
         
            +
                    highest_staff_post_number integer DEFAULT 0 NOT NULL,
         
     | 
| 
      
 81 
     | 
    
         
            +
                    featured_link character varying
         
     | 
| 
      
 82 
     | 
    
         
            +
                  );
         
     | 
| 
      
 83 
     | 
    
         
            +
                
         
     | 
| 
      
 84 
     | 
    
         
            +
                  CREATE TABLE users (
         
     | 
| 
      
 85 
     | 
    
         
            +
                    id integer NOT NULL PRIMARY KEY,
         
     | 
| 
      
 86 
     | 
    
         
            +
                    first_name character varying NOT NULL,
         
     | 
| 
      
 87 
     | 
    
         
            +
                    last_name  character varying NOT NULL
         
     | 
| 
      
 88 
     | 
    
         
            +
                  );
         
     | 
| 
      
 89 
     | 
    
         
            +
                  CREATE TABLE categories (
         
     | 
| 
      
 90 
     | 
    
         
            +
                    id integer NOT NULL PRIMARY KEY,
         
     | 
| 
      
 91 
     | 
    
         
            +
                    name character varying NOT NULL,
         
     | 
| 
      
 92 
     | 
    
         
            +
                    title  character varying NOT NULL,
         
     | 
| 
      
 93 
     | 
    
         
            +
                    description  character varying NOT NULL
         
     | 
| 
      
 94 
     | 
    
         
            +
                  );
         
     | 
| 
      
 95 
     | 
    
         
            +
                SQL
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                generate_table(Topic)
         
     | 
| 
      
 98 
     | 
    
         
            +
                generate_table(User)
         
     | 
| 
      
 99 
     | 
    
         
            +
                generate_table(Category)
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                pg.exec <<~SQL
         
     | 
| 
      
 102 
     | 
    
         
            +
                  CREATE INDEX user_id ON topics USING btree (user_id);
         
     | 
| 
      
 103 
     | 
    
         
            +
                  CREATE INDEX category_id ON topics USING btree (category_id);
         
     | 
| 
      
 104 
     | 
    
         
            +
                SQL
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                pg.exec "vacuum full analyze topics"
         
     | 
| 
      
 107 
     | 
    
         
            +
                pg.exec "vacuum full analyze users"
         
     | 
| 
      
 108 
     | 
    
         
            +
                pg.exec "vacuum full analyze categories"
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                [ActiveRecord::Base.connection, db_conn]
         
     | 
| 
      
 111 
     | 
    
         
            +
              end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
              def generate_table(klass)
         
     | 
| 
      
 114 
     | 
    
         
            +
                data =
         
     | 
| 
      
 115 
     | 
    
         
            +
                    @count_records.times.map do |id|
         
     | 
| 
      
 116 
     | 
    
         
            +
                      topic = { id: id }
         
     | 
| 
      
 117 
     | 
    
         
            +
                      klass.columns.each do |c|
         
     | 
| 
      
 118 
     | 
    
         
            +
                        topic[c.name.to_sym] = value_from_type(c.type)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      end
         
     | 
| 
      
 120 
     | 
    
         
            +
                      topic
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                klass.insert_all(data)
         
     | 
| 
      
 123 
     | 
    
         
            +
              end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
              def value_from_type(type)
         
     | 
| 
      
 126 
     | 
    
         
            +
                case type
         
     | 
| 
      
 127 
     | 
    
         
            +
                when :integer then rand(1000)
         
     | 
| 
      
 128 
     | 
    
         
            +
                when :datetime then Time.now
         
     | 
| 
      
 129 
     | 
    
         
            +
                when :boolean then false
         
     | 
| 
      
 130 
     | 
    
         
            +
                else "HELLO WORLD" * 2
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
      
 133 
     | 
    
         
            +
            end
         
     | 
    
        data/bench/topic_perf.rb
    CHANGED
    
    | 
         @@ -13,8 +13,9 @@ gemfile do 
     | 
|
| 
       13 
13 
     | 
    
         
             
              gem 'benchmark-ips'
         
     | 
| 
       14 
14 
     | 
    
         
             
              gem 'sequel', github: 'jeremyevans/sequel'
         
     | 
| 
       15 
15 
     | 
    
         
             
              gem 'sequel_pg', github: 'jeremyevans/sequel_pg', require: 'sequel'
         
     | 
| 
       16 
     | 
    
         
            -
              gem 'swift-db-postgres', github: 'deepfryed/swift-db-postgres'
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem 'swift-db-postgres', github: 'deepfryed/swift-db-postgres' # sudo apt-get install uuid-dev
         
     | 
| 
       17 
17 
     | 
    
         
             
              gem 'draper'
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem 'pry'
         
     | 
| 
       18 
19 
     | 
    
         
             
            end
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
            require 'sequel'
         
     | 
| 
         @@ -23,68 +24,14 @@ require 'memory_profiler' 
     | 
|
| 
       23 
24 
     | 
    
         
             
            require 'benchmark/ips'
         
     | 
| 
       24 
25 
     | 
    
         
             
            require 'mini_sql'
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
              :adapter => "postgresql",
         
     | 
| 
       28 
     | 
    
         
            -
              :database => "test_db"
         
     | 
| 
       29 
     | 
    
         
            -
            )
         
     | 
| 
      
 27 
     | 
    
         
            +
            require '../mini_sql/bench/shared/generate_data'
         
     | 
| 
       30 
28 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
            SQL
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
            pg.async_exec <<SQL
         
     | 
| 
       40 
     | 
    
         
            -
            CREATE TABLE topics (
         
     | 
| 
       41 
     | 
    
         
            -
                id integer NOT NULL PRIMARY KEY,
         
     | 
| 
       42 
     | 
    
         
            -
                title character varying NOT NULL,
         
     | 
| 
       43 
     | 
    
         
            -
                last_posted_at timestamp without time zone,
         
     | 
| 
       44 
     | 
    
         
            -
                created_at timestamp without time zone NOT NULL,
         
     | 
| 
       45 
     | 
    
         
            -
                updated_at timestamp without time zone NOT NULL,
         
     | 
| 
       46 
     | 
    
         
            -
                views integer DEFAULT 0 NOT NULL,
         
     | 
| 
       47 
     | 
    
         
            -
                posts_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       48 
     | 
    
         
            -
                user_id integer,
         
     | 
| 
       49 
     | 
    
         
            -
                last_post_user_id integer NOT NULL,
         
     | 
| 
       50 
     | 
    
         
            -
                reply_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       51 
     | 
    
         
            -
                featured_user1_id integer,
         
     | 
| 
       52 
     | 
    
         
            -
                featured_user2_id integer,
         
     | 
| 
       53 
     | 
    
         
            -
                featured_user3_id integer,
         
     | 
| 
       54 
     | 
    
         
            -
                avg_time integer,
         
     | 
| 
       55 
     | 
    
         
            -
                deleted_at timestamp without time zone,
         
     | 
| 
       56 
     | 
    
         
            -
                highest_post_number integer DEFAULT 0 NOT NULL,
         
     | 
| 
       57 
     | 
    
         
            -
                image_url character varying,
         
     | 
| 
       58 
     | 
    
         
            -
                like_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       59 
     | 
    
         
            -
                incoming_link_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       60 
     | 
    
         
            -
                category_id integer,
         
     | 
| 
       61 
     | 
    
         
            -
                visible boolean DEFAULT true NOT NULL,
         
     | 
| 
       62 
     | 
    
         
            -
                moderator_posts_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       63 
     | 
    
         
            -
                closed boolean DEFAULT false NOT NULL,
         
     | 
| 
       64 
     | 
    
         
            -
                archived boolean DEFAULT false NOT NULL,
         
     | 
| 
       65 
     | 
    
         
            -
                bumped_at timestamp without time zone NOT NULL,
         
     | 
| 
       66 
     | 
    
         
            -
                has_summary boolean DEFAULT false NOT NULL,
         
     | 
| 
       67 
     | 
    
         
            -
                vote_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       68 
     | 
    
         
            -
                archetype character varying DEFAULT 'regular'::character varying NOT NULL,
         
     | 
| 
       69 
     | 
    
         
            -
                featured_user4_id integer,
         
     | 
| 
       70 
     | 
    
         
            -
                notify_moderators_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       71 
     | 
    
         
            -
                spam_count integer DEFAULT 0 NOT NULL,
         
     | 
| 
       72 
     | 
    
         
            -
                pinned_at timestamp without time zone,
         
     | 
| 
       73 
     | 
    
         
            -
                score double precision,
         
     | 
| 
       74 
     | 
    
         
            -
                percent_rank double precision DEFAULT 1.0 NOT NULL,
         
     | 
| 
       75 
     | 
    
         
            -
                subtype character varying,
         
     | 
| 
       76 
     | 
    
         
            -
                slug character varying,
         
     | 
| 
       77 
     | 
    
         
            -
                deleted_by_id integer,
         
     | 
| 
       78 
     | 
    
         
            -
                participant_count integer DEFAULT 1,
         
     | 
| 
       79 
     | 
    
         
            -
                word_count integer,
         
     | 
| 
       80 
     | 
    
         
            -
                excerpt character varying(1000),
         
     | 
| 
       81 
     | 
    
         
            -
                pinned_globally boolean DEFAULT false NOT NULL,
         
     | 
| 
       82 
     | 
    
         
            -
                pinned_until timestamp without time zone,
         
     | 
| 
       83 
     | 
    
         
            -
                fancy_title character varying(400),
         
     | 
| 
       84 
     | 
    
         
            -
                highest_staff_post_number integer DEFAULT 0 NOT NULL,
         
     | 
| 
       85 
     | 
    
         
            -
                featured_link character varying
         
     | 
| 
       86 
     | 
    
         
            -
            )
         
     | 
| 
       87 
     | 
    
         
            -
            SQL
         
     | 
| 
      
 29 
     | 
    
         
            +
            ar_connection, conn_config = GenerateData.new(count_records: 1_000).call
         
     | 
| 
      
 30 
     | 
    
         
            +
            PG_CONN = ar_connection.raw_connection
         
     | 
| 
      
 31 
     | 
    
         
            +
            MINI_SQL = MiniSql::Connection.get(PG_CONN)
         
     | 
| 
      
 32 
     | 
    
         
            +
            DB = Sequel.connect(ar_connection.instance_variable_get(:@config).slice(:database, :user, :password, :host, :adapter))
         
     | 
| 
      
 33 
     | 
    
         
            +
            # connects over unix socket
         
     | 
| 
      
 34 
     | 
    
         
            +
            SWIFT = Swift::DB::Postgres.new(db: conn_config[:database], user: conn_config[:user], password: conn_config[:password], host: conn_config[:host])
         
     | 
| 
       88 
35 
     | 
    
         | 
| 
       89 
36 
     | 
    
         
             
            class Topic < ActiveRecord::Base
         
     | 
| 
       90 
37 
     | 
    
         
             
            end
         
     | 
| 
         @@ -92,26 +39,6 @@ end 
     | 
|
| 
       92 
39 
     | 
    
         
             
            class TopicSequel < Sequel::Model(:topics)
         
     | 
| 
       93 
40 
     | 
    
         
             
            end
         
     | 
| 
       94 
41 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
            Topic.transaction do
         
     | 
| 
       96 
     | 
    
         
            -
              topic = {
         
     | 
| 
       97 
     | 
    
         
            -
              }
         
     | 
| 
       98 
     | 
    
         
            -
              Topic.columns.each do |c|
         
     | 
| 
       99 
     | 
    
         
            -
                topic[c.name.to_sym] = case c.type
         
     | 
| 
       100 
     | 
    
         
            -
                                       when :integer then 1
         
     | 
| 
       101 
     | 
    
         
            -
                                       when :datetime then Time.now
         
     | 
| 
       102 
     | 
    
         
            -
                                       when :boolean then false
         
     | 
| 
       103 
     | 
    
         
            -
                                       else "HELLO WORLD" * 2
         
     | 
| 
       104 
     | 
    
         
            -
                                       end
         
     | 
| 
       105 
     | 
    
         
            -
              end
         
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
              1000.times do |id|
         
     | 
| 
       108 
     | 
    
         
            -
                topic[:id] = id
         
     | 
| 
       109 
     | 
    
         
            -
                Topic.create!(topic)
         
     | 
| 
       110 
     | 
    
         
            -
              end
         
     | 
| 
       111 
     | 
    
         
            -
            end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
            $conn = ActiveRecord::Base.connection.raw_connection
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
42 
     | 
    
         
             
            def ar_title_id_pluck
         
     | 
| 
       116 
43 
     | 
    
         
             
              s = +""
         
     | 
| 
       117 
44 
     | 
    
         
             
              Topic.limit(1000).order(:id).pluck(:id, :title).each do |id, title|
         
     | 
| 
         @@ -133,7 +60,7 @@ end 
     | 
|
| 
       133 
60 
     | 
    
         
             
            def pg_title_id
         
     | 
| 
       134 
61 
     | 
    
         
             
              s = +""
         
     | 
| 
       135 
62 
     | 
    
         
             
              # use the safe pattern here
         
     | 
| 
       136 
     | 
    
         
            -
              r =  
     | 
| 
      
 63 
     | 
    
         
            +
              r = PG_CONN.async_exec(-"select id, title from topics order by id limit 1000")
         
     | 
| 
       137 
64 
     | 
    
         | 
| 
       138 
65 
     | 
    
         
             
              # this seems fastest despite extra arrays, cause array of arrays is generated
         
     | 
| 
       139 
66 
     | 
    
         
             
              # in c code
         
     | 
| 
         @@ -150,11 +77,9 @@ def pg_title_id 
     | 
|
| 
       150 
77 
     | 
    
         
             
              s
         
     | 
| 
       151 
78 
     | 
    
         
             
            end
         
     | 
| 
       152 
79 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
            $mini_sql = MiniSql::Connection.get($conn)
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
80 
     | 
    
         
             
            def mini_sql_title_id
         
     | 
| 
       156 
81 
     | 
    
         
             
              s = +""
         
     | 
| 
       157 
     | 
    
         
            -
               
     | 
| 
      
 82 
     | 
    
         
            +
              MINI_SQL.query(-"select id, title from topics order by id limit 1000").each do |t|
         
     | 
| 
       158 
83 
     | 
    
         
             
                s << t.id.to_s
         
     | 
| 
       159 
84 
     | 
    
         
             
                s << t.title
         
     | 
| 
       160 
85 
     | 
    
         
             
              end
         
     | 
| 
         @@ -183,7 +108,7 @@ end 
     | 
|
| 
       183 
108 
     | 
    
         
             
            def mini_sql_title_id_query_single
         
     | 
| 
       184 
109 
     | 
    
         
             
              s = +""
         
     | 
| 
       185 
110 
     | 
    
         
             
              i = 0
         
     | 
| 
       186 
     | 
    
         
            -
              r =  
     | 
| 
      
 111 
     | 
    
         
            +
              r = MINI_SQL.query_single(-"select id, title from topics order by id limit 1000")
         
     | 
| 
       187 
112 
     | 
    
         
             
              while i < r.length
         
     | 
| 
       188 
113 
     | 
    
         
             
                s << r[i].to_s
         
     | 
| 
       189 
114 
     | 
    
         
             
                s << r[i + 1]
         
     | 
| 
         @@ -192,13 +117,10 @@ def mini_sql_title_id_query_single 
     | 
|
| 
       192 
117 
     | 
    
         
             
              s
         
     | 
| 
       193 
118 
     | 
    
         
             
            end
         
     | 
| 
       194 
119 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
            # connects over unix socket
         
     | 
| 
       196 
     | 
    
         
            -
            $swift = Swift::DB::Postgres.new(db: "test_db")
         
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
120 
     | 
    
         
             
            def swift_select_title_id(l = 1000)
         
     | 
| 
       199 
121 
     | 
    
         
             
              s = +''
         
     | 
| 
       200 
122 
     | 
    
         
             
              i = 0
         
     | 
| 
       201 
     | 
    
         
            -
              r =  
     | 
| 
      
 123 
     | 
    
         
            +
              r = SWIFT.execute("select id, title from topics order by id limit 1000")
         
     | 
| 
       202 
124 
     | 
    
         
             
              while i < r.selected_rows
         
     | 
| 
       203 
125 
     | 
    
         
             
                s << r.get(i, 0).to_s
         
     | 
| 
       204 
126 
     | 
    
         
             
                s << r.get(i, 1)
         
     | 
| 
         @@ -220,175 +142,6 @@ results = [ 
     | 
|
| 
       220 
142 
     | 
    
         | 
| 
       221 
143 
     | 
    
         
             
            exit(-1) unless results.uniq.length == 1
         
     | 
| 
       222 
144 
     | 
    
         | 
| 
       223 
     | 
    
         
            -
            # https://github.com/drapergem/draper
         
     | 
| 
       224 
     | 
    
         
            -
            class TopicDraper < Draper::Decorator
         
     | 
| 
       225 
     | 
    
         
            -
              delegate :id
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
     | 
    
         
            -
              def title_bang
         
     | 
| 
       228 
     | 
    
         
            -
                object.title + '!!!'
         
     | 
| 
       229 
     | 
    
         
            -
              end
         
     | 
| 
       230 
     | 
    
         
            -
            end
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
       232 
     | 
    
         
            -
            # https://ruby-doc.org/stdlib-2.5.1/libdoc/delegate/rdoc/SimpleDelegator.html
         
     | 
| 
       233 
     | 
    
         
            -
            class TopicSimpleDelegator < SimpleDelegator
         
     | 
| 
       234 
     | 
    
         
            -
              def title_bang
         
     | 
| 
       235 
     | 
    
         
            -
                title + '!!!'
         
     | 
| 
       236 
     | 
    
         
            -
              end
         
     | 
| 
       237 
     | 
    
         
            -
            end
         
     | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
       239 
     | 
    
         
            -
            class TopicDecoratorSequel < TopicSequel
         
     | 
| 
       240 
     | 
    
         
            -
              def title_bang
         
     | 
| 
       241 
     | 
    
         
            -
                title + '!!!'
         
     | 
| 
       242 
     | 
    
         
            -
              end
         
     | 
| 
       243 
     | 
    
         
            -
            end
         
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
            class TopicArModel < Topic
         
     | 
| 
       246 
     | 
    
         
            -
              def title_bang
         
     | 
| 
       247 
     | 
    
         
            -
                title + '!!!'
         
     | 
| 
       248 
     | 
    
         
            -
              end
         
     | 
| 
       249 
     | 
    
         
            -
            end
         
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
            module TopicDecorator
         
     | 
| 
       252 
     | 
    
         
            -
              def title_bang
         
     | 
| 
       253 
     | 
    
         
            -
                title + '!!!'
         
     | 
| 
       254 
     | 
    
         
            -
              end
         
     | 
| 
       255 
     | 
    
         
            -
            end
         
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
            Benchmark.ips do |r|
         
     | 
| 
       258 
     | 
    
         
            -
              r.report('query_decorator') do |n|
         
     | 
| 
       259 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       260 
     | 
    
         
            -
                  $mini_sql.query_decorator(TopicDecorator, 'select id, title from topics order by id limit 1000').each do |obj|
         
     | 
| 
       261 
     | 
    
         
            -
                    obj.title_bang
         
     | 
| 
       262 
     | 
    
         
            -
                    obj.id
         
     | 
| 
       263 
     | 
    
         
            -
                  end
         
     | 
| 
       264 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       265 
     | 
    
         
            -
                end
         
     | 
| 
       266 
     | 
    
         
            -
              end
         
     | 
| 
       267 
     | 
    
         
            -
              r.report('extend') do |n|
         
     | 
| 
       268 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       269 
     | 
    
         
            -
                  $mini_sql.query('select id, title from topics order by id limit 1000').each do |obj|
         
     | 
| 
       270 
     | 
    
         
            -
                    d_obj = obj.extend(TopicDecorator)
         
     | 
| 
       271 
     | 
    
         
            -
                    d_obj.title_bang
         
     | 
| 
       272 
     | 
    
         
            -
                    d_obj.id
         
     | 
| 
       273 
     | 
    
         
            -
                  end
         
     | 
| 
       274 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       275 
     | 
    
         
            -
                end
         
     | 
| 
       276 
     | 
    
         
            -
              end
         
     | 
| 
       277 
     | 
    
         
            -
              r.report('draper') do |n|
         
     | 
| 
       278 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       279 
     | 
    
         
            -
                  $mini_sql.query('select id, title from topics order by id limit 1000').each do |obj|
         
     | 
| 
       280 
     | 
    
         
            -
                    d_obj = TopicDraper.new(obj)
         
     | 
| 
       281 
     | 
    
         
            -
                    d_obj.title_bang
         
     | 
| 
       282 
     | 
    
         
            -
                    d_obj.id
         
     | 
| 
       283 
     | 
    
         
            -
                  end
         
     | 
| 
       284 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       285 
     | 
    
         
            -
                end
         
     | 
| 
       286 
     | 
    
         
            -
              end
         
     | 
| 
       287 
     | 
    
         
            -
              r.report('simple_delegator') do |n|
         
     | 
| 
       288 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       289 
     | 
    
         
            -
                  $mini_sql.query('select id, title from topics order by id limit 1000').each do |obj|
         
     | 
| 
       290 
     | 
    
         
            -
                    d_obj = TopicSimpleDelegator.new(obj)
         
     | 
| 
       291 
     | 
    
         
            -
                    d_obj.title_bang
         
     | 
| 
       292 
     | 
    
         
            -
                    d_obj.id
         
     | 
| 
       293 
     | 
    
         
            -
                  end
         
     | 
| 
       294 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       295 
     | 
    
         
            -
                end
         
     | 
| 
       296 
     | 
    
         
            -
              end
         
     | 
| 
       297 
     | 
    
         
            -
              r.report('query') do |n|
         
     | 
| 
       298 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       299 
     | 
    
         
            -
                  $mini_sql.query('select id, title from topics order by id limit 1000').each do |obj|
         
     | 
| 
       300 
     | 
    
         
            -
                    obj.title + '!!!'
         
     | 
| 
       301 
     | 
    
         
            -
                    obj.id
         
     | 
| 
       302 
     | 
    
         
            -
                  end
         
     | 
| 
       303 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       304 
     | 
    
         
            -
                end
         
     | 
| 
       305 
     | 
    
         
            -
              end
         
     | 
| 
       306 
     | 
    
         
            -
              r.report('ar model') do |n|
         
     | 
| 
       307 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       308 
     | 
    
         
            -
                  TopicArModel.limit(1000).order(:id).select(:id, :title).each do |obj|
         
     | 
| 
       309 
     | 
    
         
            -
                    obj.title_bang
         
     | 
| 
       310 
     | 
    
         
            -
                    obj.id
         
     | 
| 
       311 
     | 
    
         
            -
                  end
         
     | 
| 
       312 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       313 
     | 
    
         
            -
                end
         
     | 
| 
       314 
     | 
    
         
            -
              end
         
     | 
| 
       315 
     | 
    
         
            -
              r.report('sequel model') do |n|
         
     | 
| 
       316 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       317 
     | 
    
         
            -
                  TopicDecoratorSequel.limit(1000).order(:id).select(:id, :title).each do |obj|
         
     | 
| 
       318 
     | 
    
         
            -
                    obj.title_bang
         
     | 
| 
       319 
     | 
    
         
            -
                    obj.id
         
     | 
| 
       320 
     | 
    
         
            -
                  end
         
     | 
| 
       321 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       322 
     | 
    
         
            -
                end
         
     | 
| 
       323 
     | 
    
         
            -
              end
         
     | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
       325 
     | 
    
         
            -
              r.compare!
         
     | 
| 
       326 
     | 
    
         
            -
            end
         
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
       328 
     | 
    
         
            -
            # Comparison:
         
     | 
| 
       329 
     | 
    
         
            -
            #                query:      828.4 i/s
         
     | 
| 
       330 
     | 
    
         
            -
            #      query_decorator:      819.3 i/s - same-ish: difference falls within error
         
     | 
| 
       331 
     | 
    
         
            -
            #         sequel model:      672.4 i/s - 1.23x  slower
         
     | 
| 
       332 
     | 
    
         
            -
            #               extend:      519.4 i/s - 1.59x  slower
         
     | 
| 
       333 
     | 
    
         
            -
            #     simple_delegator:      496.8 i/s - 1.67x  slower
         
     | 
| 
       334 
     | 
    
         
            -
            #               draper:      416.2 i/s - 1.99x  slower
         
     | 
| 
       335 
     | 
    
         
            -
            #             ar model:      113.4 i/s - 7.30x  slower
         
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
            Benchmark.ips do |r|
         
     | 
| 
       338 
     | 
    
         
            -
              r.report('query_hash') do |n|
         
     | 
| 
       339 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       340 
     | 
    
         
            -
                  $mini_sql.query_hash('select id, title from topics order by id limit 1000').each do |hash|
         
     | 
| 
       341 
     | 
    
         
            -
                    [hash['id'], hash['title']]
         
     | 
| 
       342 
     | 
    
         
            -
                  end
         
     | 
| 
       343 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       344 
     | 
    
         
            -
                end
         
     | 
| 
       345 
     | 
    
         
            -
              end
         
     | 
| 
       346 
     | 
    
         
            -
              r.report('query_array') do |n|
         
     | 
| 
       347 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       348 
     | 
    
         
            -
                  $mini_sql.query_array('select id, title from topics order by id limit 1000').each do |id, title|
         
     | 
| 
       349 
     | 
    
         
            -
                    [id, title]
         
     | 
| 
       350 
     | 
    
         
            -
                  end
         
     | 
| 
       351 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       352 
     | 
    
         
            -
                end
         
     | 
| 
       353 
     | 
    
         
            -
              end
         
     | 
| 
       354 
     | 
    
         
            -
              r.report('query') do |n|
         
     | 
| 
       355 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       356 
     | 
    
         
            -
                  $mini_sql.query('select id, title from topics order by id limit 1000').each do |obj|
         
     | 
| 
       357 
     | 
    
         
            -
                    [obj.id, obj.title]
         
     | 
| 
       358 
     | 
    
         
            -
                  end
         
     | 
| 
       359 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       360 
     | 
    
         
            -
                end
         
     | 
| 
       361 
     | 
    
         
            -
              end
         
     | 
| 
       362 
     | 
    
         
            -
             
     | 
| 
       363 
     | 
    
         
            -
              r.compare!
         
     | 
| 
       364 
     | 
    
         
            -
            end
         
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
            # Comparison:
         
     | 
| 
       367 
     | 
    
         
            -
            #         query_array:     1351.6 i/s
         
     | 
| 
       368 
     | 
    
         
            -
            #               query:      963.8 i/s - 1.40x  slower
         
     | 
| 
       369 
     | 
    
         
            -
            #          query_hash:      787.4 i/s - 1.72x  slower
         
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
            Benchmark.ips do |r|
         
     | 
| 
       372 
     | 
    
         
            -
              r.report('query_single') do |n|
         
     | 
| 
       373 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       374 
     | 
    
         
            -
                  $mini_sql.query_single('select id from topics order by id limit 1000')
         
     | 
| 
       375 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       376 
     | 
    
         
            -
                end
         
     | 
| 
       377 
     | 
    
         
            -
              end
         
     | 
| 
       378 
     | 
    
         
            -
              r.report('query_array') do |n|
         
     | 
| 
       379 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       380 
     | 
    
         
            -
                  $mini_sql.query_array('select id from topics order by id limit 1000').flatten
         
     | 
| 
       381 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       382 
     | 
    
         
            -
                end
         
     | 
| 
       383 
     | 
    
         
            -
              end
         
     | 
| 
       384 
     | 
    
         
            -
             
     | 
| 
       385 
     | 
    
         
            -
              r.compare!
         
     | 
| 
       386 
     | 
    
         
            -
            end
         
     | 
| 
       387 
     | 
    
         
            -
             
     | 
| 
       388 
     | 
    
         
            -
            # Comparison:
         
     | 
| 
       389 
     | 
    
         
            -
            #        query_single:     2368.9 i/s
         
     | 
| 
       390 
     | 
    
         
            -
            #         query_array:     1350.1 i/s - 1.75x  slower
         
     | 
| 
       391 
     | 
    
         
            -
             
     | 
| 
       392 
145 
     | 
    
         
             
            Benchmark.ips do |r|
         
     | 
| 
       393 
146 
     | 
    
         
             
              r.report("ar select title id") do |n|
         
     | 
| 
       394 
147 
     | 
    
         
             
                while n > 0
         
     | 
| 
         @@ -441,71 +194,12 @@ Benchmark.ips do |r| 
     | 
|
| 
       441 
194 
     | 
    
         
             
              r.compare!
         
     | 
| 
       442 
195 
     | 
    
         
             
            end
         
     | 
| 
       443 
196 
     | 
    
         | 
| 
       444 
     | 
    
         
            -
            def wide_topic_ar
         
     | 
| 
       445 
     | 
    
         
            -
              Topic.first
         
     | 
| 
       446 
     | 
    
         
            -
            end
         
     | 
| 
       447 
     | 
    
         
            -
             
     | 
| 
       448 
     | 
    
         
            -
            def wide_topic_pg
         
     | 
| 
       449 
     | 
    
         
            -
              r = $conn.async_exec("select * from topics limit 1")
         
     | 
| 
       450 
     | 
    
         
            -
              row = r.first
         
     | 
| 
       451 
     | 
    
         
            -
              r.clear
         
     | 
| 
       452 
     | 
    
         
            -
              row
         
     | 
| 
       453 
     | 
    
         
            -
            end
         
     | 
| 
       454 
     | 
    
         
            -
             
     | 
| 
       455 
     | 
    
         
            -
            def wide_topic_sequel
         
     | 
| 
       456 
     | 
    
         
            -
              TopicSequel.first
         
     | 
| 
       457 
     | 
    
         
            -
            end
         
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
     | 
    
         
            -
            def wide_topic_mini_sql
         
     | 
| 
       460 
     | 
    
         
            -
              $conn.query("select * from topics limit 1").first
         
     | 
| 
       461 
     | 
    
         
            -
            end
         
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
            Benchmark.ips do |r|
         
     | 
| 
       464 
     | 
    
         
            -
              r.report("wide topic ar") do |n|
         
     | 
| 
       465 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       466 
     | 
    
         
            -
                  wide_topic_ar
         
     | 
| 
       467 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       468 
     | 
    
         
            -
                end
         
     | 
| 
       469 
     | 
    
         
            -
              end
         
     | 
| 
       470 
     | 
    
         
            -
              r.report("wide topic sequel") do |n|
         
     | 
| 
       471 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       472 
     | 
    
         
            -
                  wide_topic_sequel
         
     | 
| 
       473 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       474 
     | 
    
         
            -
                end
         
     | 
| 
       475 
     | 
    
         
            -
              end
         
     | 
| 
       476 
     | 
    
         
            -
              r.report("wide topic pg") do |n|
         
     | 
| 
       477 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       478 
     | 
    
         
            -
                  wide_topic_pg
         
     | 
| 
       479 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       480 
     | 
    
         
            -
                end
         
     | 
| 
       481 
     | 
    
         
            -
              end
         
     | 
| 
       482 
     | 
    
         
            -
              r.report("wide topic mini sql") do |n|
         
     | 
| 
       483 
     | 
    
         
            -
                while n > 0
         
     | 
| 
       484 
     | 
    
         
            -
                  wide_topic_mini_sql
         
     | 
| 
       485 
     | 
    
         
            -
                  n -= 1
         
     | 
| 
       486 
     | 
    
         
            -
                end
         
     | 
| 
       487 
     | 
    
         
            -
              end
         
     | 
| 
       488 
     | 
    
         
            -
              r.compare!
         
     | 
| 
       489 
     | 
    
         
            -
            end
         
     | 
| 
       490 
     | 
    
         
            -
             
     | 
| 
       491 
197 
     | 
    
         
             
            # Comparison:
         
     | 
| 
       492 
     | 
    
         
            -
            #   pg select title id: 
     | 
| 
       493 
     | 
    
         
            -
            #  
     | 
| 
       494 
     | 
    
         
            -
            #  
     | 
| 
       495 
     | 
    
         
            -
            # mini_sql select title id: 
     | 
| 
       496 
     | 
    
         
            -
            # 
     | 
| 
       497 
     | 
    
         
            -
            # sequel title id select: 
     | 
| 
       498 
     | 
    
         
            -
            # ar select title id pluck: 
     | 
| 
       499 
     | 
    
         
            -
            #   ar select title id: 
     | 
| 
       500 
     | 
    
         
            -
            #
         
     | 
| 
       501 
     | 
    
         
            -
            #
         
     | 
| 
       502 
     | 
    
         
            -
            # Comparison:
         
     | 
| 
       503 
     | 
    
         
            -
            #        wide topic pg:     7474.0 i/s
         
     | 
| 
       504 
     | 
    
         
            -
            #  wide topic mini sql:     7355.2 i/s - same-ish: difference falls within error
         
     | 
| 
       505 
     | 
    
         
            -
            #    wide topic sequel:     5696.8 i/s - 1.31x  slower
         
     | 
| 
       506 
     | 
    
         
            -
            #        wide topic ar:     2515.0 i/s - 2.97x  slower
         
     | 
| 
       507 
     | 
    
         
            -
             
     | 
| 
       508 
     | 
    
         
            -
            # to run deep analysis run
         
     | 
| 
       509 
     | 
    
         
            -
            # MemoryProfiler.report do
         
     | 
| 
       510 
     | 
    
         
            -
            #   ar
         
     | 
| 
       511 
     | 
    
         
            -
            # end.pretty_print
         
     | 
| 
      
 198 
     | 
    
         
            +
            #   pg select title id:               1315.1 i/s
         
     | 
| 
      
 199 
     | 
    
         
            +
            #       swift title id:               1268.4 i/s - same-ish: difference falls within error
         
     | 
| 
      
 200 
     | 
    
         
            +
            # mini_sql query_single title id:     1206.3 i/s - same-ish: difference falls within error
         
     | 
| 
      
 201 
     | 
    
         
            +
            # mini_sql select title id:           1063.8 i/s - 1.24x  (± 0.00) slower
         
     | 
| 
      
 202 
     | 
    
         
            +
            # sequel title id pluck:              1054.5 i/s - 1.25x  (± 0.00) slower
         
     | 
| 
      
 203 
     | 
    
         
            +
            # sequel title id select:              814.1 i/s - 1.62x  (± 0.00) slower
         
     | 
| 
      
 204 
     | 
    
         
            +
            # ar select title id pluck:            667.7 i/s - 1.97x  (± 0.00) slower
         
     | 
| 
      
 205 
     | 
    
         
            +
            #   ar select title id:                215.8 i/s - 6.09x  (± 0.00) slower
         
     |