fast-polylines 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3a21f83abca7c1b9ef3bb824145ceea3189fbdb9d428a2faff1daa94e2a50fb
4
- data.tar.gz: 0e6578cb705d0121daadb0a019bedd2d0d1b2589b2905134f933f4ae0859d3e2
3
+ metadata.gz: 2b799fba2f53eb5a319d237b5460cfc20185bbe757108420ed4a2c95414ab3b5
4
+ data.tar.gz: 7853302b6843e13d4ce0161be04c4deb514a4bbd62e3c0f2fd334c00ef3b6d72
5
5
  SHA512:
6
- metadata.gz: 16c293fc12361086fc39002b10fd81faaeb68632e4c6e670de1c2ec242b8277a7c453da2e5f1a9176104ccdafab99447807871f8afdb09188d97f07ed6a307d0
7
- data.tar.gz: e48e91654bc2746c4c36d3d6ce744914941ec4966f1aa6b56bbe61cacdcce841dc936b997dd477794ad8a0546ebb7c9317afc007dc1b9f74dd630d9de5d2f417
6
+ metadata.gz: 5381b5bcaa24e8dc5a6d397dc514fdeed8dc20c894a855385ba78af691e10bab8442b9d93329af658a6a8eba3a26716aff3fb3f9f2a238ca1cc1d5dea4a10243
7
+ data.tar.gz: '08733692f3f9e7ac461434f57b82b0c689e981eac015f57c92a7be94ae0195f72a283695e876120018f14aa8f8be6095640bf86631eb166701af17f601b624f4'
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Implementation of the [Google polyline algorithm][algorithm].
7
7
 
8
- **BREAKING CHANGES:** The version 2.0.0 of FastPolylines includes breaking changes, see [Migrate from 1.0.0](#migrate-from-1.0.0)
8
+ **BREAKING CHANGES:** The version 2 of FastPolylines includes breaking changes, see [Migrate from V1](#migrate-from-V1)
9
9
 
10
10
 
11
11
  About **300x faster encoding and decoding** than [Joshua Clayton's gem][polylines].
@@ -16,35 +16,35 @@ About **300x faster encoding and decoding** than [Joshua Clayton's gem][polylin
16
16
  ——————————————————————————————— ENCODING ————————————————————————————————
17
17
 
18
18
  Warming up --------------------------------------
19
- Polylines 277.000 i/100ms
20
- FastPolylinesV1 2.050k i/100ms
21
- FastPolylinesV2 73.822k i/100ms
19
+ Polylines 310.000 i/100ms
20
+ FastPolylinesV1 2.607k i/100ms
21
+ FastPolylinesV2 59.833k i/100ms
22
22
  Calculating -------------------------------------
23
- Polylines 3.254k1.8%) i/s - 16.343k in 5.023767s
24
- FastPolylinesV1 25.715k3.7%) i/s - 129.150k in 5.029675s
25
- FastPolylinesV2 933.751k4.3%) i/s - 4.725M in 5.072446s
23
+ Polylines 2.957k5.9%) i/s - 14.880k in 5.049867s
24
+ FastPolylinesV1 25.644k5.8%) i/s - 127.743k in 4.999954s
25
+ FastPolylinesV2 682.981k7.7%) i/s - 3.410M in 5.025952s
26
26
 
27
27
  Comparison:
28
- FastPolylinesV2: 933750.7 i/s
29
- FastPolylinesV1: 25715.1 i/s - 36.31x slower
30
- Polylines: 3254.3 i/s - 286.93x slower
28
+ FastPolylinesV2: 682980.7 i/s
29
+ FastPolylinesV1: 25643.7 i/s - 26.63x slower
30
+ Polylines: 2957.1 i/s - 230.97x slower
31
31
 
32
32
 
33
33
  ——————————————————————————————— DECODING ————————————————————————————————
34
34
 
35
35
  Warming up --------------------------------------
36
- Polylines 140.000 i/100ms
37
- FastPolylinesV1 1.602k i/100ms
38
- FastPolylinesV2 36.432k i/100ms
36
+ Polylines 127.000 i/100ms
37
+ FastPolylinesV1 1.225k i/100ms
38
+ FastPolylinesV2 40.667k i/100ms
39
39
  Calculating -------------------------------------
40
- Polylines 1.401k2.2%) i/s - 7.000k in 5.000321s
41
- FastPolylinesV1 16.465k3.7%) i/s - 83.304k in 5.067786s
42
- FastPolylinesV2 396.100k5.2%) i/s - 2.004M in 5.074500s
40
+ Polylines 1.289k6.1%) i/s - 6.477k in 5.046552s
41
+ FastPolylinesV1 15.445k4.4%) i/s - 77.175k in 5.006896s
42
+ FastPolylinesV2 468.413k7.8%) i/s - 2.359M in 5.068936s
43
43
 
44
44
  Comparison:
45
- FastPolylinesV2: 396100.0 i/s
46
- FastPolylinesV1: 16464.6 i/s - 24.06x slower
47
- Polylines: 1400.6 i/s - 282.81x slower
45
+ FastPolylinesV2: 468412.8 i/s
46
+ FastPolylinesV1: 15445.4 i/s - 30.33x slower
47
+ Polylines: 1288.8 i/s - 363.46x slower
48
48
  ```
49
49
 
50
50
  ## Install
@@ -61,7 +61,7 @@ gem "fast-polylines", "~> 2.0.0"
61
61
  ## Usage
62
62
 
63
63
  ```ruby
64
- require "fast-polylines"
64
+ require "fast_polylines"
65
65
 
66
66
  FastPolylines.encode([[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]])
67
67
  # "_p~iF~ps|U_ulLnnqC_mqNvxq`@"
@@ -74,7 +74,7 @@ FastPolylines.decode("_p~iF~ps|U_ulLnnqC_mqNvxq`@")
74
74
 
75
75
  **Use a different precision**
76
76
 
77
- Default precision is `5` decimals, to use a precision of `6` decimals:
77
+ Default precision is `5` decimals, to use a precision of `6`:
78
78
  ```ruby
79
79
  FastPolylines.encode([[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]], 6)
80
80
  # "_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI"
@@ -84,17 +84,21 @@ FastPolylines.decode("_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI", 6)
84
84
  ```
85
85
  The precision max is `13`.
86
86
 
87
- ## Migrate from 1.0.0
87
+ ## Migrate from V1
88
88
 
89
89
  **TL;DR:**
90
90
 
91
91
  ```ruby
92
92
  # before
93
+ require "fast-polylines"
93
94
  FastPolylines::Encoder.encode([[1.2, 1.2], [2.4, 2.4]], 1e6)
94
95
  # after
96
+ require "fast_polylines"
95
97
  FastPolylines.encode([[1.2, 1.2], [2.4, 2.4]], 6)
96
98
  ```
97
99
 
100
+ **Detailled:**
101
+
98
102
  The new version of `FastPolylines` doesn't support precision more than `1e13`,
99
103
  you should not consider using it anyway since [it is way too precise][xkcd].
100
104
 
@@ -106,6 +110,9 @@ The precision is now an integer representing the number of decimals. It is
106
110
  slightly smaller, and mostly this will avoid having any float value as
107
111
  precision.
108
112
 
113
+ The file name to require is now snake_cased, you'll have to require
114
+ `fast_polylines`. The gem name stays the same however.
115
+
109
116
  ## Run the Benchmark
110
117
 
111
118
  You can run the benchmark with `make benchmark`.
@@ -1,4 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "mkmf"
4
+
5
+ if ENV["DEBUG"]
6
+ warn "DEBUG MODE."
7
+ $CFLAGS << " " << %w(
8
+ -Wall
9
+ -ggdb
10
+ -DDEBUG
11
+ -pedantic
12
+ ) * " "
13
+ end
4
14
  create_makefile "fast_polylines/fast_polylines"
@@ -72,15 +72,18 @@ rb_FastPolylines__decode(int argc, VALUE *argv, VALUE self) {
72
72
 
73
73
  static inline uint8_t
74
74
  _polyline_encode_number(char *chunks, int64_t number) {
75
+ dbg("_polyline_encode_number(\"%s\", %lli)\n", chunks, number);
75
76
  number = number < 0 ? ~(number << 1) : (number << 1);
76
77
  uint8_t i = 0;
77
- while (number > 0x20) {
78
+ while (number >= 0x20) {
78
79
  uint8_t chunk = number & 0x1f;
79
80
  chunks[i++] = (0x20 | chunk) + 63;
80
81
  number = number >> 5;
81
82
  }
82
- dbg("%u encoded chunks\n", i);
83
83
  chunks[i++] = number + 63;
84
+ dbg("%u encoded chunks\n", i);
85
+ dbg("chunks: %s\n", chunks);
86
+ dbg("/_polyline_encode_number");
84
87
  return i;
85
88
  }
86
89
 
@@ -108,6 +111,7 @@ rb_FastPolylines__encode(int argc, VALUE *argv, VALUE self) {
108
111
  for (i = 0; i < len; i++) {
109
112
  current_pair = RARRAY_AREF(argv[0], i);
110
113
  uint8_t j;
114
+ Check_Type(current_pair, T_ARRAY);
111
115
  if (RARRAY_LEN(current_pair) != 2) {
112
116
  free(chunks);
113
117
  rb_raise(rb_eArgError, "wrong number of coordinates");
@@ -136,6 +140,7 @@ rb_FastPolylines__encode(int argc, VALUE *argv, VALUE self) {
136
140
  // We pass a pointer to the current chunk that need to be filled. Doing so
137
141
  // avoid having to copy the string every single iteration.
138
142
  chunks_index += _polyline_encode_number(chunks + chunks_index * sizeof(char), delta);
143
+ dbg("%s\n", chunks);
139
144
  }
140
145
  }
141
146
  dbg("final chunks_index: %zu\n", chunks_index);
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FastPolylines
4
- VERSION = "2.0.0"
4
+ VERSION = "2.0.1"
5
5
  end
@@ -1,10 +1,8 @@
1
- require "spec_helper"
2
-
3
1
  describe FastPolylines do
4
2
  describe ".decode" do
5
3
  let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
4
+ let(:polyline) { "_p~iF~ps|U_ulLnnqC_mqNvxq`@" }
6
5
  context "with default precision" do
7
- let(:polyline) { "_p~iF~ps|U_ulLnnqC_mqNvxq`@" }
8
6
  it "should decode a polyline correctly" do
9
7
  expect(described_class.decode(polyline)).to eq points
10
8
  end
@@ -47,9 +45,34 @@ describe FastPolylines do
47
45
  end
48
46
 
49
47
  describe ".encode" do
50
- let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
48
+ let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
49
+ let(:polyline) { "_p~iF~ps|U_ulLnnqC_mqNvxq`@" }
50
+ it "should raise for invalid input" do
51
+ expect { described_class.encode(points[0]) }.to raise_error(
52
+ TypeError,
53
+ "wrong argument type Float (expected Array)"
54
+ )
55
+ expect { described_class.encode([points]) }.to raise_error(
56
+ ArgumentError,
57
+ "wrong number of coordinates"
58
+ )
59
+ expect { described_class.encode([points[0..1]]) }.to raise_error(
60
+ TypeError,
61
+ "no implicit conversion to Float from Array"
62
+ )
63
+ end
64
+ # The method `_polyline_encode_number("", 16)` will check for a chunk
65
+ # of the size 32, which is the chunk size limit. This was errored due to
66
+ # a bad sign.
67
+ # Reported in issue #15, closed in PR #16
68
+ context "with points close to the chunk size limit" do
69
+ let(:points) { [[0, 0.00016]] }
70
+ let(:polyline) { "?_@" }
71
+ it "should encode points correctly" do
72
+ expect(described_class.encode(points)).to eq polyline
73
+ end
74
+ end
51
75
  context "with default precision" do
52
- let(:polyline) { "_p~iF~ps|U_ulLnnqC_mqNvxq`@" }
53
76
  it "should encode points correctly" do
54
77
  expect(described_class.encode(points)).to eq polyline
55
78
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
3
 
4
+ $LOAD_PATH.unshift File.join(__dir__, "..", "lib")
5
+ $LOAD_PATH.unshift File.join(__dir__, "..", "ext")
6
+
4
7
  require "fast_polylines"
5
8
 
6
9
  RSpec.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast-polylines
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyrille Courtière
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-03-26 00:00:00.000000000 Z
12
+ date: 2020-04-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: benchmark-ips
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  requirements: []
91
- rubygems_version: 3.0.2
91
+ rubygems_version: 3.1.0.pre3
92
92
  signing_key:
93
93
  specification_version: 4
94
94
  summary: Fast & easy Google polylines