base62-rb 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41ababc33c9761ec527aa12e739ee3a3335fae10
4
- data.tar.gz: 7e9d24d5da22aef6f43a02aad978d9654eb2728d
3
+ metadata.gz: 299f76e841055f3d30cc34ff3795eac2e212e283
4
+ data.tar.gz: 80b78e4e05f4c5740050e753cca18e7def48fe7b
5
5
  SHA512:
6
- metadata.gz: 096fc1a781be8088931c95b83f33d42c415535f10f3de2a9331461831ba709a2e330afa81100f2025cd512b8f612782aed1d7ad904e9e53586d9c6b3928161c9
7
- data.tar.gz: f495b8ef1151b4e842b8af79cfd237a4120c9b73180c083c78078f3c03c80d99668f37da33e067dc47becfa15675488d544ed6b814a2fc373c1b00c19fd08a73
6
+ metadata.gz: 214f81b6a1919b075db0924bbd1f80dedab436f14a4b699421f838d2eeae24f0e2b17626b3e10d2706ae9cad3770dc8063e5a487f1fcc1f734aae787cb81ef8d
7
+ data.tar.gz: d1b0000f0512a29e98b3f5f0556079b3f81e8ccfe39cb30013e4d4532dd083dee4ba85ebc0b5ae7b8eb8b68427a993df30c12122843ed4d780e791b95e2eb229
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Steven Yue
1
+ Copyright (c) 2016 Steven Yue
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Base62 in Ruby
2
2
 
3
- A simple and fast implementation of base62 in pure Ruby without too much sugar and magic.
3
+ A simple and fast implementation of base62 in pure Ruby without too much sugar and magic.
4
4
 
5
5
  It uses character set: `0-9`, `a-z`, `A-Z` for encoding and decoding.
6
6
 
@@ -41,4 +41,4 @@ See the comparison [here](benchmarks/comparison.rb)
41
41
 
42
42
  ## License
43
43
 
44
- MIT License - Copyright (c) 2014 Steven Yue
44
+ MIT License - Copyright (c) 2016 Steven Yue
@@ -15,7 +15,6 @@ time = Benchmark.measure do
15
15
  end
16
16
  puts time # => 3.280000 0.010000 3.290000 ( 3.311349))
17
17
 
18
-
19
18
  # gem radix62 v1.0.1
20
19
  # https://github.com/matiaskorhonen/radix62
21
20
  require 'radix62'
@@ -28,7 +27,6 @@ time = Benchmark.measure do
28
27
  end
29
28
  puts time # => 6.790000 0.020000 6.810000 ( 6.842925)
30
29
 
31
-
32
30
  # gem base62 v1.0.0
33
31
  # https://github.com/jtzemp/base62
34
32
  require 'base62'
@@ -39,4 +37,4 @@ time = Benchmark.measure do
39
37
  raise "Assertion error!" unless i == decode
40
38
  end
41
39
  end
42
- puts time # => 10.370000 0.030000 10.400000 ( 10.452976)
40
+ puts time # => 10.370000 0.030000 10.400000 ( 10.452976)
@@ -0,0 +1,161 @@
1
+ require 'benchmark/ips'
2
+
3
+ KEYS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
4
+ KEYS_HASH = KEYS.each_char.with_index.inject({}){|h,(k,v)| h[k]=v;h}
5
+ BASE = KEYS.length
6
+
7
+ ### Decode Method Candidates =====
8
+
9
+ # The one that is used in base62-rb library
10
+ # Use 'while' loop, and define a variable i as the counter
11
+ def decode(str)
12
+ num = 0
13
+ i = 0
14
+ len = str.length - 1
15
+ while i < str.length
16
+ pow = BASE ** (len - i)
17
+ num += KEYS_HASH[str[i]] * pow
18
+ i += 1
19
+ end
20
+ return num
21
+ end
22
+
23
+ # Use KEYS.index to get the index
24
+ # instead of using a predefined Hash Map(KEYS_HASH)
25
+ def decode1(str)
26
+ num = 0
27
+ i = 0
28
+ while i < str.length
29
+ pow = BASE ** (str.length - i -1)
30
+ num += KEYS.index(str[i]) * pow
31
+ i += 1
32
+ end
33
+ return num
34
+ end
35
+
36
+ # Use 'for...in...' loop
37
+ def decode2(str)
38
+ num = 0
39
+ for i in 0...str.length
40
+ pow = BASE ** (str.length - i -1)
41
+ num += KEYS_HASH[str[i]] * pow
42
+ end
43
+ return num
44
+ end
45
+
46
+ # Use String#each_char, and #with_index
47
+ # Use block to do the calcuation
48
+ def decode3(str)
49
+ num = 0
50
+ str.each_char.with_index do |char, i|
51
+ pow = BASE ** (str.length - i -1)
52
+ num += KEYS.index(char) * pow
53
+ end
54
+ return num
55
+ end
56
+
57
+ # Similar as above, but use KEYS_HASH to get the index
58
+ def decode4(str)
59
+ num = 0
60
+ str.each_char.with_index do |char, i|
61
+ pow = BASE ** (str.length - i -1)
62
+ num += KEYS_HASH[char] * pow
63
+ end
64
+ return num
65
+ end
66
+
67
+ # Similar as above, but explicitly define the counter
68
+ # without using #with_index
69
+ def decode5(str)
70
+ num = 0
71
+ i = 0
72
+ str.each_char do |char|
73
+ pow = BASE ** (str.length - i -1)
74
+ num += KEYS_HASH[char] * pow
75
+ i += 1
76
+ end
77
+ return num
78
+ end
79
+
80
+ # same thing but with less variable
81
+ def decode6(str)
82
+ num = 0
83
+ i = 0
84
+ while i < str.length
85
+ num += KEYS_HASH[str[i]] * (BASE ** (str.length - 1 - i))
86
+ i += 1
87
+ end
88
+ return num
89
+ end
90
+
91
+ ### ==================
92
+
93
+ ### Testing =====
94
+
95
+ tests = ["A", "Jr", "DFL", "2B5S", "8zTZmv", "1AnE6bpNA", "hjNv8tS3K"]
96
+
97
+ Benchmark.ips do |x|
98
+ x.report("decode") do
99
+ tests.each do |test|
100
+ decode(test)
101
+ end
102
+ end
103
+
104
+ x.report("decode1") do
105
+ tests.each do |test|
106
+ decode1(test)
107
+ end
108
+ end
109
+
110
+ x.report("decode2") do
111
+ tests.each do |test|
112
+ decode2(test)
113
+ end
114
+ end
115
+
116
+ x.report("decode3") do
117
+ tests.each do |test|
118
+ decode3(test)
119
+ end
120
+ end
121
+
122
+ x.report("decode4") do
123
+ tests.each do |test|
124
+ decode4(test)
125
+ end
126
+ end
127
+
128
+ x.report("decode5") do
129
+ tests.each do |test|
130
+ decode5(test)
131
+ end
132
+ end
133
+
134
+ x.report("decode6") do
135
+ tests.each do |test|
136
+ decode6(test)
137
+ end
138
+ end
139
+ end
140
+
141
+ ### Results
142
+
143
+ # Results tested on Macbook Air 1.4 GHz Intel Core i5, 8 GB 1600 MHz DDR3
144
+ # Using Ruby 2.1.3p242
145
+
146
+ # Calculating -------------------------------------
147
+ # decode 6677 i/100ms
148
+ # decode1 5962 i/100ms
149
+ # decode2 5535 i/100ms
150
+ # decode3 4378 i/100ms
151
+ # decode4 4502 i/100ms
152
+ # decode5 5915 i/100ms
153
+ # decode6 6443 i/100ms
154
+ # -------------------------------------------------
155
+ # decode 67891.4 (±9.7%) i/s - 340527 in 5.069726s
156
+ # decode1 62385.4 (±7.8%) i/s - 310024 in 5.000584s
157
+ # decode2 57033.8 (±8.5%) i/s - 287820 in 5.082882s
158
+ # decode3 45356.5 (±6.5%) i/s - 227656 in 5.041103s
159
+ # decode4 47708.3 (±6.5%) i/s - 238606 in 5.023164s
160
+ # decode5 64856.4 (±6.6%) i/s - 325325 in 5.038748s
161
+ # decode6 67880.8 (±7.4%) i/s - 341479 in 5.059089s
@@ -0,0 +1,129 @@
1
+ require 'benchmark/ips'
2
+
3
+ KEYS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
4
+ KEYS_HASH = KEYS.each_char.with_index.inject({}){|h,(k,v)| h[k]=v;h}
5
+ BASE = KEYS.length
6
+
7
+ ### Encode Method Candidates =====
8
+
9
+ # The one that is used in base62-rb library
10
+ # Use '+' to prepend string
11
+ def encode(num)
12
+ return "0" if num == 0
13
+ return nil if num < 0
14
+
15
+ str = ""
16
+ while num > 0
17
+ str = KEYS[num % BASE] + str
18
+ num = num / BASE
19
+ end
20
+ return str
21
+ end
22
+
23
+ # Use String#reverse method at the end
24
+ def encode1(num)
25
+ return "0" if num == 0
26
+ return nil if num < 0
27
+
28
+ str = ""
29
+ while num > 0
30
+ str = str + KEYS[num % BASE]
31
+ num = num / (BASE)
32
+ end
33
+ return str.reverse
34
+ end
35
+
36
+ # Use String#prepend method
37
+ def encode2(num)
38
+ return "0" if num == 0
39
+ return nil if num < 0
40
+
41
+ str = ""
42
+ while num > 0
43
+ str.prepend KEYS[num % BASE]
44
+ num = num / (BASE)
45
+ end
46
+ return str
47
+ end
48
+
49
+ # Use the '/=' way
50
+ def encode3(num)
51
+ return "0" if num == 0
52
+ return nil if num < 0
53
+
54
+ str = ""
55
+ while num > 0
56
+ str = KEYS[num % BASE] + str
57
+ num /= BASE
58
+ end
59
+ return str
60
+ end
61
+
62
+ # Use #<< to append string
63
+ def encode4(num)
64
+ return "0" if num == 0
65
+ return nil if num < 0
66
+
67
+ str = ""
68
+ while num > 0
69
+ str << KEYS[num % BASE]
70
+ num /= BASE
71
+ end
72
+ return str.reverse
73
+ end
74
+
75
+ ### ==================
76
+
77
+ ### Testing =====
78
+
79
+ tests_encode = [630, 1231, 902323, 3781504209452600, 18446744073709551615]
80
+
81
+ Benchmark.ips do |x|
82
+ x.report("encode") do
83
+ tests_encode.each do |test|
84
+ encode(test)
85
+ end
86
+ end
87
+
88
+ x.report("encode1") do
89
+ tests_encode.each do |test|
90
+ encode1(test)
91
+ end
92
+ end
93
+
94
+ x.report("encode2") do
95
+ tests_encode.each do |test|
96
+ encode2(test)
97
+ end
98
+ end
99
+
100
+ x.report("encode3") do
101
+ tests_encode.each do |test|
102
+ encode3(test)
103
+ end
104
+ end
105
+
106
+ x.report("encode4") do
107
+ tests_encode.each do |test|
108
+ encode4(test)
109
+ end
110
+ end
111
+ end
112
+
113
+ ### Results
114
+
115
+ # Results tested on Macbook Air 1.4 GHz Intel Core i5, 8 GB 1600 MHz DDR3
116
+ # Using Ruby 2.1.3p242
117
+
118
+ # Calculating -------------------------------------
119
+ # encode 9141 i/100ms
120
+ # encode1 8231 i/100ms
121
+ # encode2 7222 i/100ms
122
+ # encode3 9040 i/100ms
123
+ # encode4 8660 i/100ms
124
+ # -------------------------------------------------
125
+ # encode 97414.2 (±8.1%) i/s - 484473 in 5.008219s
126
+ # encode1 89976.1 (±6.5%) i/s - 452705 in 5.053138s
127
+ # encode2 76680.4 (±6.8%) i/s - 382766 in 5.015263s
128
+ # encode3 94348.1 (±8.2%) i/s - 470080 in 5.016213s
129
+ # encode4 86996.4 (±8.7%) i/s - 433000 in 5.016085s
@@ -1,35 +1,35 @@
1
1
  require "base62/version"
2
2
 
3
3
  module Base62
4
- KEYS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
5
- KEYS_HASH = KEYS.each_char.with_index.inject({}){ |h,(k,v)| h[k]=v; h }
6
- BASE = KEYS.length
4
+ KEYS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".freeze
5
+ KEYS_HASH = KEYS.each_char.with_index.inject({}) { |h, (k, v)| h[k] = v; h }
6
+ BASE = KEYS.length
7
7
 
8
- # Encodes base10 (decimal) number to base62 string.
9
- def self.encode(num)
10
- return "0" if num == 0
11
- return nil if num < 0
8
+ # Encodes base10 (decimal) number to base62 string.
9
+ def self.encode(num)
10
+ return "0" if num == 0
11
+ return nil if num < 0
12
12
 
13
- str = ""
14
- while num > 0
15
- # prepend base62 charaters
16
- str = KEYS[num % BASE] + str
17
- num = num / BASE
18
- end
19
- return str
20
- end
13
+ str = ""
14
+ while num > 0
15
+ # prepend base62 charaters
16
+ str = KEYS[num % BASE] + str
17
+ num = num / BASE
18
+ end
19
+ str
20
+ end
21
21
 
22
- # Decodes base62 string to a base10 (decimal) number.
23
- def self.decode(str)
24
- num = 0
25
- i = 0
26
- len = str.length - 1
27
- # while loop is faster than each_char or other 'idiomatic' way
28
- while i < str.length
29
- pow = BASE ** (len - i)
30
- num += KEYS_HASH[str[i]] * pow
31
- i += 1
32
- end
33
- return num
34
- end
35
- end
22
+ # Decodes base62 string to a base10 (decimal) number.
23
+ def self.decode(str)
24
+ num = 0
25
+ i = 0
26
+ len = str.length - 1
27
+ # while loop is faster than each_char or other 'idiomatic' way
28
+ while i < str.length
29
+ pow = BASE**(len - i)
30
+ num += KEYS_HASH[str[i]] * pow
31
+ i += 1
32
+ end
33
+ num
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module Base62
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -2,27 +2,27 @@ require "base62-rb"
2
2
  require "test/unit"
3
3
 
4
4
  class Base62Test < Test::Unit::TestCase
5
- def test_encode
6
- {
7
- 0 => "0",
8
- 3781504209452600 => "hjNv8tS3K",
9
- 18446744073709551615 => "lYGhA16ahyf"
10
- }.each do |int, base62|
11
- assert_equal base62, Base62.encode(int)
12
- end
13
- end
5
+ def test_encode
6
+ {
7
+ 0 => "0",
8
+ 3781504209452600 => "hjNv8tS3K",
9
+ 18446744073709551615 => "lYGhA16ahyf"
10
+ }.each do |int, base62|
11
+ assert_equal base62, Base62.encode(int)
12
+ end
13
+ end
14
14
 
15
- def test_decode
16
- {
17
- "0" => 0,
18
- "hjNv8tS3K" => 3781504209452600,
19
- "lYGhA16ahyf" => 18446744073709551615
20
- }.each do |base62, int|
21
- assert_equal int, Base62.decode(base62)
22
- end
23
- end
15
+ def test_decode
16
+ {
17
+ "0" => 0,
18
+ "hjNv8tS3K" => 3781504209452600,
19
+ "lYGhA16ahyf" => 18446744073709551615
20
+ }.each do |base62, int|
21
+ assert_equal int, Base62.decode(base62)
22
+ end
23
+ end
24
24
 
25
- def test_negative_numbers
26
- assert_nil Base62.encode(-123)
27
- end
28
- end
25
+ def test_negative_numbers
26
+ assert_nil Base62.encode(-123)
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: base62-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Yue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-27 00:00:00.000000000 Z
11
+ date: 2016-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,8 @@ files:
52
52
  - Rakefile
53
53
  - base62-rb.gemspec
54
54
  - benchmarks/comparison.rb
55
+ - benchmarks/decode_bench.rb
56
+ - benchmarks/encode_bench.rb
55
57
  - lib/base62-rb.rb
56
58
  - lib/base62/version.rb
57
59
  - test/base62_test.rb
@@ -75,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
77
  version: '0'
76
78
  requirements: []
77
79
  rubyforge_project:
78
- rubygems_version: 2.2.2
80
+ rubygems_version: 2.5.1
79
81
  signing_key:
80
82
  specification_version: 4
81
83
  summary: Fast Base62 encoding and decoding in Ruby