fast_blank 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +21 -0
- data/README.md +57 -0
- data/benchmark +40 -0
- data/ext/fast_blank/extconf.rb +2 -0
- data/ext/fast_blank/fast_blank.c +83 -0
- data/lib/.gemkeep +0 -0
- data/spec/fast_blank_spec.rb +51 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 23b988d318c1c1da6a788a6d0c3b1f7f0f65e6ca
|
4
|
+
data.tar.gz: ba4ef389e4cebb24ba9ac8e1fc8c5d263b817d94
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88222e2184cf6394fd34fb5840e8ca30013e68cac6ea2f0a5408252eafe97a121db72baa42ec10bee14d7ae1ccced2f66974fcfa76c3d999f989050fe183b118
|
7
|
+
data.tar.gz: 74e3a6270528702e72428564215614a81564e2a475dfe797db27ebb5780d9cb8e452f7fc458767cbfea9a127de0ab6607879733bbee6e8916c8ac72231c55693
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2006-2009 Steve Sloan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
### String blank? Ruby Extension
|
2
|
+
|
3
|
+
`fast_blank` is a simple extension which provides a fast implementation of active support's string#blank? function
|
4
|
+
|
5
|
+
### How do you use it?
|
6
|
+
|
7
|
+
require 'fast_blank'
|
8
|
+
|
9
|
+
### How fast is "Fast"?
|
10
|
+
|
11
|
+
|
12
|
+
About 5-9x faster than current active support, on my machine (your mileage my vary):
|
13
|
+
|
14
|
+
$ ./benchmark
|
15
|
+
|
16
|
+
```
|
17
|
+
user system total real
|
18
|
+
user system total real
|
19
|
+
Fast Blank 0 : 0.070000 0.000000 0.070000 ( 0.075247)
|
20
|
+
Fast Blank (Active Support) 0 : 0.080000 0.000000 0.080000 ( 0.075029)
|
21
|
+
Slow Blank 0 : 0.500000 0.000000 0.500000 ( 0.503026)
|
22
|
+
Fast Blank 6 : 0.200000 0.000000 0.200000 ( 0.191480)
|
23
|
+
Fast Blank (Active Support) 6 : 0.180000 0.000000 0.180000 ( 0.179891)
|
24
|
+
Slow Blank 6 : 0.660000 0.000000 0.660000 ( 0.658604)
|
25
|
+
Fast Blank 14 : 0.080000 0.010000 0.090000 ( 0.086371)
|
26
|
+
Fast Blank (Active Support) 14 : 0.130000 0.000000 0.130000 ( 0.129258)
|
27
|
+
Slow Blank 14 : 0.890000 0.000000 0.890000 ( 0.886140)
|
28
|
+
Fast Blank 24 : 0.150000 0.000000 0.150000 ( 0.158151)
|
29
|
+
Fast Blank (Active Support) 24 : 0.140000 0.000000 0.140000 ( 0.149284)
|
30
|
+
Slow Blank 24 : 0.900000 0.000000 0.900000 ( 0.899663)
|
31
|
+
Fast Blank 136 : 0.130000 0.000000 0.130000 ( 0.125831)
|
32
|
+
Fast Blank (Active Support) 136 : 0.150000 0.000000 0.150000 ( 0.148948)
|
33
|
+
Slow Blank 136 : 0.900000 0.000000 0.900000 ( 0.899885)
|
34
|
+
|
35
|
+
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
Additionally, this gem allocates no strings during the test, making it less of a GC burden.
|
40
|
+
|
41
|
+
|
42
|
+
###Compatability note:
|
43
|
+
|
44
|
+
fast_blank implements string.blank? as MRI would have it implemented, meaning it has 100% parity with `String#strip.length == 0`.
|
45
|
+
|
46
|
+
|
47
|
+
Active Supports version looks also at unicode spaces
|
48
|
+
for example: `"\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000".blank?` is true in Active Support even though fast_blank would treat it as not blank.
|
49
|
+
|
50
|
+
fast_blank also provides blank_as? which is a 100% compatible blank? replacement.
|
51
|
+
|
52
|
+
Author: Sam Saffron sam.saffron@gmail.com
|
53
|
+
http://github.com/SamSaffron/fast_blank
|
54
|
+
License: MIT
|
55
|
+
|
56
|
+
|
57
|
+
(gem template based on https://github.com/CodeMonkeySteve/fast_xor )
|
data/benchmark
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.dirname(__FILE__)+'/lib'
|
3
|
+
require 'benchmark'
|
4
|
+
require 'fast_blank'
|
5
|
+
|
6
|
+
class String
|
7
|
+
# active support implementation
|
8
|
+
def slow_blank?
|
9
|
+
self !~ /[^[:space:]]/
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
n = 1000000
|
15
|
+
|
16
|
+
|
17
|
+
strings = [
|
18
|
+
"",
|
19
|
+
"\r\n\r\n ",
|
20
|
+
"this is a test",
|
21
|
+
" this is a longer test",
|
22
|
+
" this is a longer test
|
23
|
+
this is a longer test
|
24
|
+
this is a longer test
|
25
|
+
this is a longer test
|
26
|
+
this is a longer test"
|
27
|
+
]
|
28
|
+
|
29
|
+
strings.each do |s|
|
30
|
+
raise "failed on #{s.inspect}" if s.blank? != s.slow_blank?
|
31
|
+
end
|
32
|
+
|
33
|
+
Benchmark.bmbm do |x|
|
34
|
+
strings.each do |s|
|
35
|
+
x.report("Fast Blank #{s.length} :") do n.times { s.blank? } end
|
36
|
+
x.report("Fast Blank (Active Support) #{s.length} :") do n.times { s.blank_as? } end
|
37
|
+
x.report("Slow Blank #{s.length} :") do n.times { s.slow_blank? } end
|
38
|
+
#x.report("Empty #{s.length} :") do n.times { s.empty? } end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <ruby.h>
|
3
|
+
#include <ruby/encoding.h>
|
4
|
+
#include <ruby/re.h>
|
5
|
+
|
6
|
+
#define STR_ENC_GET(str) rb_enc_from_index(ENCODING_GET(str))
|
7
|
+
|
8
|
+
/* Backward compatibility with Ruby 1.8 */
|
9
|
+
#ifndef RSTRING_PTR
|
10
|
+
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
11
|
+
#endif
|
12
|
+
#ifndef RSTRING_LEN
|
13
|
+
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
14
|
+
#endif
|
15
|
+
|
16
|
+
const unsigned int as_blank[26] = {9, 0xa, 0xb, 0xc, 0xd,
|
17
|
+
0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2000, 0x2001,
|
18
|
+
0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008,
|
19
|
+
0x2009, 0x200a, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000
|
20
|
+
};
|
21
|
+
|
22
|
+
static VALUE
|
23
|
+
rb_str_blank_as(VALUE str)
|
24
|
+
{
|
25
|
+
rb_encoding *enc;
|
26
|
+
char *s, *e;
|
27
|
+
int i;
|
28
|
+
int found;
|
29
|
+
|
30
|
+
enc = STR_ENC_GET(str);
|
31
|
+
s = RSTRING_PTR(str);
|
32
|
+
if (!s || RSTRING_LEN(str) == 0) return Qtrue;
|
33
|
+
|
34
|
+
e = RSTRING_END(str);
|
35
|
+
while (s < e) {
|
36
|
+
int n;
|
37
|
+
unsigned int cc = rb_enc_codepoint_len(s, e, &n, enc);
|
38
|
+
|
39
|
+
found = 0;
|
40
|
+
for(i=0;i<26;i++){
|
41
|
+
unsigned int current = as_blank[i];
|
42
|
+
if(current == cc) {
|
43
|
+
found = 1;
|
44
|
+
break;
|
45
|
+
}
|
46
|
+
if(cc < current){
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
if (!found) return Qfalse;
|
52
|
+
s += n;
|
53
|
+
}
|
54
|
+
return Qtrue;
|
55
|
+
}
|
56
|
+
|
57
|
+
static VALUE
|
58
|
+
rb_str_blank(VALUE str)
|
59
|
+
{
|
60
|
+
rb_encoding *enc;
|
61
|
+
char *s, *e;
|
62
|
+
|
63
|
+
enc = STR_ENC_GET(str);
|
64
|
+
s = RSTRING_PTR(str);
|
65
|
+
if (!s || RSTRING_LEN(str) == 0) return Qtrue;
|
66
|
+
|
67
|
+
e = RSTRING_END(str);
|
68
|
+
while (s < e) {
|
69
|
+
int n;
|
70
|
+
unsigned int cc = rb_enc_codepoint_len(s, e, &n, enc);
|
71
|
+
|
72
|
+
if (!rb_isspace(cc) && cc != 0) return Qfalse;
|
73
|
+
s += n;
|
74
|
+
}
|
75
|
+
return Qtrue;
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
void Init_fast_blank( void )
|
80
|
+
{
|
81
|
+
rb_define_method(rb_cString, "blank?", rb_str_blank, 0);
|
82
|
+
rb_define_method(rb_cString, "blank_as?", rb_str_blank_as, 0);
|
83
|
+
}
|
data/lib/.gemkeep
ADDED
File without changes
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'fast_blank'
|
2
|
+
|
3
|
+
class ::String
|
4
|
+
def blank2?
|
5
|
+
self !~ /[^[:space:]]/
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe String do
|
10
|
+
it "works" do
|
11
|
+
"".blank?.should == true
|
12
|
+
" ".blank?.should == true
|
13
|
+
"\r\n".blank?.should == true
|
14
|
+
"\r\n\v\f\r\s\u0085".blank? == true
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
it "provides a parity with active support function" do
|
19
|
+
(16*16*16*16).times do |i|
|
20
|
+
c = i.chr('UTF-8') rescue nil
|
21
|
+
unless c.nil?
|
22
|
+
"#{i.to_s(16)} #{c.blank_as?}".should == "#{i.to_s(16)} #{c.blank2?}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
(256).times do |i|
|
28
|
+
c = i.chr('ASCII') rescue nil
|
29
|
+
unless c.nil?
|
30
|
+
"#{i.to_s(16)} #{c.blank_as?}".should == "#{i.to_s(16)} #{c.blank2?}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has parity with strip.length" do
|
36
|
+
(256).times do |i|
|
37
|
+
c = i.chr('ASCII') rescue nil
|
38
|
+
unless c.nil?
|
39
|
+
"#{i.to_s(16)} #{c.strip.length == 0}".should == "#{i.to_s(16)} #{c.blank?}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "treats \u0000 correctly" do
|
45
|
+
# odd I know
|
46
|
+
"\u0000".strip.length.should == 0
|
47
|
+
"\u0000".blank_as?.should be_false
|
48
|
+
"\u0000".blank?.should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fast_blank
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam Saffron
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Provides a C-optimized method for determining if a string is blank
|
56
|
+
email: sam.saffron@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions:
|
59
|
+
- ext/fast_blank/extconf.rb
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- MIT-LICENSE
|
63
|
+
- README.md
|
64
|
+
- benchmark
|
65
|
+
- lib/.gemkeep
|
66
|
+
- ext/fast_blank/fast_blank.c
|
67
|
+
- ext/fast_blank/extconf.rb
|
68
|
+
- spec/fast_blank_spec.rb
|
69
|
+
homepage: ''
|
70
|
+
licenses: []
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.0.2
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Fast String blank? implementation
|
92
|
+
test_files:
|
93
|
+
- spec/fast_blank_spec.rb
|