extralite 1.8.2 → 1.9
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/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
|
[](http://rubygems.org/gems/extralite)
|
4
4
|
[](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
|