hescape 0.1.0 → 0.1.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 +5 -5
- data/.rspec +2 -0
- data/README.md +70 -0
- data/Rakefile +11 -0
- data/ext/hescape/hescape.c +3 -2
- data/hescape.gemspec +1 -0
- data/lib/hescape/version.rb +1 -1
- data/wercker.yml +3 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d9ee8060d3f4a049a27ea234820dc709212b3bc7fc65eb9ec68cb16d8916d9c1
|
4
|
+
data.tar.gz: aed8550ea57d0a43a701c5c9d016d1f7104173aeb5d0dbbdb6c0480262bd9577
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65978b80e047b7a59eec90463e153e4d2e9526d3b972be5231f5d02a2606b83e413ce0dc7bc81c825e3483847d833b3ae1d97cad58248e63d10802366ece009c
|
7
|
+
data.tar.gz: 41f9109130c0e0e1211f587b2e54a2d2167c9b84ddbc56bff38b3a46e76fc400e045bbc2836525b5b7a4416eb92521f159b8c33b9aadc9b857267e740c76ef72
|
data/.rspec
ADDED
data/README.md
CHANGED
@@ -2,6 +2,76 @@
|
|
2
2
|
|
3
3
|
A gem to use [hescape](https://github.com/k0kubun/hescape) from Ruby, which is fast HTML escape implementation using SSE instructions.
|
4
4
|
|
5
|
+
## Benchmark
|
6
|
+
|
7
|
+
See [the result](https://app.wercker.com/k0kubun/hescape-ruby/runs/build/57b09e1de8960a01001b3811) of [this benchmark](https://github.com/k0kubun/hescape-ruby/blob/v0.1.0/benchmark/benchmark.rb). Followings are the result of:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
Benchmark.ips do |x|
|
11
|
+
str = ENV['ESCAPE_STRING']
|
12
|
+
puts "escaping: #{str}"
|
13
|
+
|
14
|
+
escape_table = { "'" => ''', '&' => '&', '"' => '"', '<' => '<', '>' => '>', }
|
15
|
+
|
16
|
+
x.report('gsub') { str.gsub(/['&\"<>]/, escape_table) }
|
17
|
+
x.report('escape_utils') { EscapeUtils.escape_html(str, false) }
|
18
|
+
x.report('cgi/escape') { CGI.escapeHTML(str) }
|
19
|
+
x.report('hescape') { Hescape.escape_html(str) }
|
20
|
+
x.compare!
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
### No escape
|
25
|
+
```
|
26
|
+
escaping: https://github.com/k0kubun/hescape-ruby
|
27
|
+
Calculating -------------------------------------
|
28
|
+
gsub 2.392M (± 1.0%) i/s - 11.983M in 5.010225s
|
29
|
+
escape_utils 2.365M (± 0.3%) i/s - 11.896M in 5.031031s
|
30
|
+
cgi/escape 3.787M (± 8.0%) i/s - 18.965M in 5.037529s
|
31
|
+
hescape 7.515M (± 0.3%) i/s - 37.736M in 5.021293s
|
32
|
+
|
33
|
+
Comparison:
|
34
|
+
hescape: 7515215.8 i/s
|
35
|
+
cgi/escape: 3787425.3 i/s - 1.98x slower
|
36
|
+
gsub: 2391950.1 i/s - 3.14x slower
|
37
|
+
escape_utils: 2364604.2 i/s - 3.18x slower
|
38
|
+
```
|
39
|
+
|
40
|
+
### Short escape
|
41
|
+
Note: If given string is short, hescape skips SSE instruction. But it's fast.
|
42
|
+
|
43
|
+
```
|
44
|
+
escaping: <script />
|
45
|
+
Calculating -------------------------------------
|
46
|
+
gsub 586.604k (± 1.8%) i/s - 2.941M in 5.015840s
|
47
|
+
escape_utils 2.948M (± 0.3%) i/s - 14.781M in 5.014237s
|
48
|
+
cgi/escape 2.646M (± 1.7%) i/s - 13.226M in 5.000218s
|
49
|
+
hescape 3.731M (± 0.3%) i/s - 18.661M in 5.001429s
|
50
|
+
|
51
|
+
Comparison:
|
52
|
+
hescape: 3731246.4 i/s
|
53
|
+
escape_utils: 2947868.9 i/s - 1.27x slower
|
54
|
+
cgi/escape: 2645937.6 i/s - 1.41x slower
|
55
|
+
gsub: 586604.3 i/s - 6.36x slower
|
56
|
+
```
|
57
|
+
|
58
|
+
### Long escape
|
59
|
+
|
60
|
+
```
|
61
|
+
escaping: <<<<<<<<<<>>>>>>>>>&&&&&&&&&&""""""'''''
|
62
|
+
Calculating -------------------------------------
|
63
|
+
gsub 66.181k (± 0.4%) i/s - 331.968k in 5.016150s
|
64
|
+
escape_utils 749.600k (± 8.1%) i/s - 3.762M in 5.053210s
|
65
|
+
cgi/escape 720.474k (± 1.6%) i/s - 3.628M in 5.037395s
|
66
|
+
hescape 754.412k (± 8.2%) i/s - 3.801M in 5.070904s
|
67
|
+
|
68
|
+
Comparison:
|
69
|
+
hescape: 754411.6 i/s
|
70
|
+
escape_utils: 749600.4 i/s - same-ish: difference falls within error
|
71
|
+
cgi/escape: 720473.5 i/s - same-ish: difference falls within error
|
72
|
+
gsub: 66181.0 i/s - 11.40x slower
|
73
|
+
```
|
74
|
+
|
5
75
|
## Installation
|
6
76
|
|
7
77
|
Add this line to your application's Gemfile:
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/extensiontask"
|
3
|
+
require "rspec/core/rake_task"
|
3
4
|
|
4
5
|
task :build => :compile
|
5
6
|
|
@@ -8,3 +9,13 @@ Rake::ExtensionTask.new("hescape") do |ext|
|
|
8
9
|
end
|
9
10
|
|
10
11
|
task :default => [:clobber, :compile, :spec]
|
12
|
+
|
13
|
+
begin
|
14
|
+
require "rspec/core/rake_task"
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new(:spec)
|
17
|
+
|
18
|
+
task :spec => :build
|
19
|
+
rescue LoadError
|
20
|
+
# no rspec available
|
21
|
+
end
|
data/ext/hescape/hescape.c
CHANGED
@@ -98,17 +98,18 @@ find_escape_fast(const char *buf, size_t i, size_t size, int *found)
|
|
98
98
|
__m128i escapes5 = _mm_loadu_si128((const __m128i *)escapes);
|
99
99
|
size_t left = (size - i) & ~15;
|
100
100
|
do {
|
101
|
-
__m128i b16 = _mm_loadu_si128((void *)buf);
|
101
|
+
__m128i b16 = _mm_loadu_si128((void *)(buf + i));
|
102
102
|
int index = _mm_cmpestri(escapes5, 5, b16, 16, _SIDD_CMP_EQUAL_ANY);
|
103
103
|
if (unlikely(index != 16)) {
|
104
104
|
i += index;
|
105
105
|
*found = 1;
|
106
|
-
|
106
|
+
return i;
|
107
107
|
}
|
108
108
|
i += 16;
|
109
109
|
left -= 16;
|
110
110
|
} while(likely(left != 0));
|
111
111
|
}
|
112
|
+
*found = 0;
|
112
113
|
return i;
|
113
114
|
}
|
114
115
|
#endif
|
data/hescape.gemspec
CHANGED
data/lib/hescape/version.rb
CHANGED
data/wercker.yml
CHANGED
@@ -5,6 +5,9 @@ build:
|
|
5
5
|
- script:
|
6
6
|
name: compile
|
7
7
|
code: bundle exec rake compile
|
8
|
+
- script:
|
9
|
+
name: spec
|
10
|
+
code: bundle exec rake spec
|
8
11
|
- script:
|
9
12
|
name: "[bench] no escape"
|
10
13
|
code: ESCAPE_STRING="https://github.com/k0kubun/hescape-ruby" bundle exec ruby benchmark/benchmark.rb
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hescape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.5'
|
83
97
|
description: Fast HTML escape utility
|
84
98
|
email:
|
85
99
|
- takashikkbn@gmail.com
|
@@ -89,6 +103,7 @@ extensions:
|
|
89
103
|
extra_rdoc_files: []
|
90
104
|
files:
|
91
105
|
- ".gitignore"
|
106
|
+
- ".rspec"
|
92
107
|
- Gemfile
|
93
108
|
- LICENSE.txt
|
94
109
|
- README.md
|
@@ -123,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
138
|
version: '0'
|
124
139
|
requirements: []
|
125
140
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.
|
141
|
+
rubygems_version: 2.7.6
|
127
142
|
signing_key:
|
128
143
|
specification_version: 4
|
129
144
|
summary: Fast HTML escape utility
|