fast_blank 0.0.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.
@@ -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
@@ -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
+
@@ -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 )
@@ -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,2 @@
1
+ require 'mkmf'
2
+ create_makefile 'fast_blank'
@@ -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
+ }
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