extralite 1.8.2 → 1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +28 -18
- data/ext/extralite/extralite.c +1 -1
- data/lib/extralite/version.rb +1 -1
- data/test/perf_ary.rb +51 -0
- data/test/{perf.rb → perf_hash.rb} +0 -0
- data/test/test_database.rb +17 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 874f2ebc573b23e4336b69409252b2cbb8c71c1275b1ca34d1d1924999d8ed31
|
4
|
+
data.tar.gz: 5b304d82a818c3e0da2dd72bca6fa590ff8be84241c6dc54fdb9f3bee49e498a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd039c09306a04eb1e1cd42eb968c58cbf7693fd09c31587e9b7853a061c2a607af9d594859510f6cabc2ef5f166426a5a0ae4459b40168b10ea3fc4c6e3063f
|
7
|
+
data.tar.gz: 2b65161b0ec69a8072e8e2f343386d8178194d1dae3bfc2ac16e414f5682d2ca1da501057f1da38cf875238e0314aa35032dcdbbf3d610affe14fb572713435a
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github: ciconia
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Extralite - a Ruby gem for working with SQLite3 databases
|
1
|
+
# Extralite - a fast Ruby gem for working with SQLite3 databases
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/extralite.svg)](http://rubygems.org/gems/extralite)
|
4
4
|
[![Modulation Test](https://github.com/digital-fabric/extralite/workflows/Tests/badge.svg)](https://github.com/digital-fabric/extralite/actions?query=workflow%3ATests)
|
@@ -6,9 +6,9 @@
|
|
6
6
|
|
7
7
|
## What is Extralite?
|
8
8
|
|
9
|
-
Extralite is
|
10
|
-
wrapper for Ruby. It provides a single class with a minimal set of methods
|
11
|
-
|
9
|
+
Extralite is a fast, extra-lightweight (less than 460 lines of C-code) SQLite3
|
10
|
+
wrapper for Ruby. It provides a single class with a minimal set of methods for
|
11
|
+
interacting with an SQLite3 database.
|
12
12
|
|
13
13
|
## Features
|
14
14
|
|
@@ -127,7 +127,7 @@ Here's a table summarizing the differences between the two gems:
|
|
127
127
|
|custom collations|yes|no|
|
128
128
|
|custom aggregate functions|yes|no|
|
129
129
|
|Multithread friendly|no|[yes](#what-about-concurrency)|
|
130
|
-
|Code size|~2650LoC|~
|
130
|
+
|Code size|~2650LoC|~530LoC|
|
131
131
|
|Performance|1x|1.5x to 12.5x (see [below](#performance))|
|
132
132
|
|
133
133
|
## What about concurrency?
|
@@ -140,23 +140,33 @@ performance:
|
|
140
140
|
|
141
141
|
## Performance
|
142
142
|
|
143
|
-
A benchmark script is
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
times faster than `sqlite3` when fetching a large number of rows. Here are the
|
148
|
-
results (using the `sqlite3` gem performance as baseline):
|
143
|
+
A benchmark script is included, creating a table of various row counts, then
|
144
|
+
fetching the entire table using either `sqlite3` or `extralite`. This benchmark
|
145
|
+
shows Extralite to be up to 12.5 times faster than `sqlite3` when fetching a
|
146
|
+
large number of rows. Here are the [results for fetching rows as hashes](https://github.com/digital-fabric/extralite/blob/main/test/perf_hash.rb):
|
149
147
|
|
150
|
-
|Row count|sqlite3-ruby
|
151
|
-
|
152
|
-
|10|
|
153
|
-
|1K|
|
154
|
-
|100K|
|
148
|
+
|Row count|sqlite3-ruby|Extralite|Advantage|
|
149
|
+
|-:|-:|-:|-:|
|
150
|
+
|10|57620 rows/s|95340 rows/s|__1.65x__|
|
151
|
+
|1K|286.8K rows/s|2106.4 rows/s|__7.35x__|
|
152
|
+
|100K|181K rows/s|2275.3K rows/s|__12.53x__|
|
153
|
+
|
154
|
+
When [fetching rows as arrays](https://github.com/digital-fabric/extralite/blob/main/test/perf_ary.rb) Extralite also significantly outperforms sqlite3-ruby:
|
155
|
+
|
156
|
+
|Row count|sqlite3-ruby|Extralite|Advantage|
|
157
|
+
|-:|-:|-:|-:|
|
158
|
+
|10|64365 rows/s|94031 rows/s|__1.46x__|
|
159
|
+
|1K|498.9K rows/s|2478.2K rows/s|__4.97x__|
|
160
|
+
|100K|441.1K rows/s|3023.4K rows/s|__6.85x__|
|
155
161
|
|
156
162
|
(If you're interested in checking this yourself, just run the script and let me
|
157
|
-
know if your results are
|
163
|
+
know if your results are better/worse.)
|
164
|
+
|
165
|
+
As those benchmarks show, Extralite is capabale of reading more than 3M
|
166
|
+
rows/second (when fetching rows as arrays), and more than 2.2M rows/second (when
|
167
|
+
fetching rows as hashes.)
|
158
168
|
|
159
169
|
## Contributing
|
160
170
|
|
161
171
|
Contributions in the form of issues, PRs or comments will be greatly
|
162
|
-
appreciated!
|
172
|
+
appreciated!
|
data/ext/extralite/extralite.c
CHANGED
@@ -116,7 +116,7 @@ inline VALUE get_column_value(sqlite3_stmt *stmt, int col, int type) {
|
|
116
116
|
case SQLITE_TEXT:
|
117
117
|
return rb_str_new_cstr((char *)sqlite3_column_text(stmt, col));
|
118
118
|
case SQLITE_BLOB:
|
119
|
-
|
119
|
+
return rb_str_new((const char *)sqlite3_column_blob(stmt, col), (long)sqlite3_column_bytes(stmt, col));
|
120
120
|
default:
|
121
121
|
rb_raise(cError, "Unknown column type: %d", type);
|
122
122
|
}
|
data/lib/extralite/version.rb
CHANGED
data/test/perf_ary.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
source 'https://rubygems.org'
|
7
|
+
gem 'sqlite3'
|
8
|
+
gem 'extralite', path: '..'
|
9
|
+
gem 'benchmark-ips'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'benchmark/ips'
|
13
|
+
require 'fileutils'
|
14
|
+
|
15
|
+
DB_PATH = '/tmp/extralite_sqlite3_perf.db'
|
16
|
+
|
17
|
+
def prepare_database(count)
|
18
|
+
FileUtils.rm(DB_PATH) rescue nil
|
19
|
+
db = Extralite::Database.new(DB_PATH)
|
20
|
+
db.query('create table foo ( a integer primary key, b text )')
|
21
|
+
db.query('begin')
|
22
|
+
count.times { db.query('insert into foo (b) values (?)', "hello#{rand(1000)}" )}
|
23
|
+
db.query('commit')
|
24
|
+
end
|
25
|
+
|
26
|
+
def sqlite3_run(count)
|
27
|
+
db = SQLite3::Database.new(DB_PATH)
|
28
|
+
results = db.execute('select * from foo')
|
29
|
+
raise unless results.size == count
|
30
|
+
end
|
31
|
+
|
32
|
+
def extralite_run(count)
|
33
|
+
db = Extralite::Database.new(DB_PATH)
|
34
|
+
results = db.query_ary('select * from foo')
|
35
|
+
raise unless results.size == count
|
36
|
+
end
|
37
|
+
|
38
|
+
[10, 1000, 100000].each do |c|
|
39
|
+
puts; puts; puts "Record count: #{c}"
|
40
|
+
|
41
|
+
prepare_database(c)
|
42
|
+
|
43
|
+
Benchmark.ips do |x|
|
44
|
+
x.config(:time => 3, :warmup => 1)
|
45
|
+
|
46
|
+
x.report("sqlite3") { sqlite3_run(c) }
|
47
|
+
x.report("extralite") { extralite_run(c) }
|
48
|
+
|
49
|
+
x.compare!
|
50
|
+
end
|
51
|
+
end
|
File without changes
|
data/test/test_database.rb
CHANGED
@@ -138,6 +138,23 @@ end
|
|
138
138
|
r = @db.query('select x, y, z from t where z = :bazzz', ':bazzz' => 6)
|
139
139
|
assert_equal [{ x: 4, y: 5, z: 6 }], r
|
140
140
|
end
|
141
|
+
|
142
|
+
def test_value_casting
|
143
|
+
r = @db.query_single_value("select 'abc'")
|
144
|
+
assert_equal 'abc', r
|
145
|
+
|
146
|
+
r = @db.query_single_value('select 123')
|
147
|
+
assert_equal 123, r
|
148
|
+
|
149
|
+
r = @db.query_single_value('select 12.34')
|
150
|
+
assert_equal 12.34, r
|
151
|
+
|
152
|
+
r = @db.query_single_value('select zeroblob(4)')
|
153
|
+
assert_equal "\x00\x00\x00\x00", r
|
154
|
+
|
155
|
+
r = @db.query_single_value('select null')
|
156
|
+
assert_nil r
|
157
|
+
end
|
141
158
|
end
|
142
159
|
|
143
160
|
class ScenarioTest < MiniTest::Test
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: extralite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.9'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
@@ -88,6 +88,7 @@ extensions:
|
|
88
88
|
extra_rdoc_files:
|
89
89
|
- README.md
|
90
90
|
files:
|
91
|
+
- ".github/FUNDING.yml"
|
91
92
|
- ".github/workflows/test.yml"
|
92
93
|
- ".gitignore"
|
93
94
|
- CHANGELOG.md
|
@@ -105,7 +106,8 @@ files:
|
|
105
106
|
- lib/extralite/version.rb
|
106
107
|
- lib/sequel/adapters/extralite.rb
|
107
108
|
- test/helper.rb
|
108
|
-
- test/
|
109
|
+
- test/perf_ary.rb
|
110
|
+
- test/perf_hash.rb
|
109
111
|
- test/run.rb
|
110
112
|
- test/test_database.rb
|
111
113
|
- test/test_sequel.rb
|