kmp 0.1.0 → 0.2.0

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
  SHA1:
3
- metadata.gz: e04c7a5db40803de18e97fc8a9344333a24564c7
4
- data.tar.gz: 3e84aa406dde540db0777c52ac910937f392c150
3
+ metadata.gz: f7d9ef58fc7947f5b3f2901cf4c52e7ad3e5ad99
4
+ data.tar.gz: 68909c1f9efaeef13ef684828c13b7e4c01b29aa
5
5
  SHA512:
6
- metadata.gz: 8378a07e3ef333d753997415784b82839bcf33a6792d9ed2aba9299fbd63c23ca2559d62e326282589a852caefec5752615068928ac147065ae25d8179193317
7
- data.tar.gz: 3f012d995f4e9d71bf4be6a01490ce075e52505a8cfa5e474169d4d2965406b01158992fca3b7635e3657f6d938a21bd8271dd239595bcd7056d7c44f5a9f15a
6
+ metadata.gz: 8cf863aaf38f13b29b0a8b1a5ddb2da28457e31d8064e2f0265614d3457ce653da7221984e58e0d424409c4a97018ffc3bbebaef4c8cd4a282a0752564c59deb
7
+ data.tar.gz: 378da39201d4cc1f38dfc6d99b249731fcfaf5ca91c3c3fe665a33627d7716dd64e8af00f0ce9fd6d5d78be45b645b2f7acf67354affdb9b3c5961f6180537b5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
1
  ## v0.1.0
2
2
  * initial release
3
3
  * implement kmp algorithm
4
+
5
+ ## v0.2.0
6
+ * memory allocation bug fix
7
+ * make function pointer constant
8
+ * improve code standard
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kmp (0.1.0)
4
+ kmp (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
  [![Build Status](https://travis-ci.org/tanvir002700/kmp.svg?branch=master)](https://travis-ci.org/tanvir002700/kmp)
3
3
  [![Maintainability](https://api.codeclimate.com/v1/badges/69f40101eeb294c05163/maintainability)](https://codeclimate.com/github/tanvir002700/kmp/maintainability)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/tanvir002700/kmp/badge.svg?branch=master)](https://coveralls.io/github/tanvir002700/kmp?branch=master)
5
+ [![Gem Version](https://badge.fury.io/rb/kmp.svg)](https://badge.fury.io/rb/kmp)
6
+ [![Downloads](https://img.shields.io/gem/dt/kmp.svg)](https://rubygems.org/gems/kmp)
5
7
  [![GitHub last commit (branch)](https://img.shields.io/github/last-commit/tanvir002700/kmp/master.svg)](https://github.com/tanvir002700/kmp)
6
8
  [![license](https://img.shields.io/github/license/tanvir002700/kmp.svg)](https://github.com/tanvir002700/kmp/blob/master/LICENSE)
7
9
 
@@ -39,6 +41,82 @@ k.length #=> 7
39
41
  - match function complexity O(N+M), N original text string length, M match string length
40
42
  - length complexity O(1)
41
43
 
44
+ ## Benchmark
45
+ This benchmark between kmp implementation in c-extenstion vs pure ruby. [Benchmark](http://ruby-doc.org/stdlib-2.0.0/libdoc/benchmark/rdoc/Benchmark.html) module use for comparison.
46
+
47
+ ```
48
+ lenght of string: 500
49
+ Rehearsal -----------------------------------------------
50
+ c-extension 0.000000 0.000000 0.000000 ( 0.000028)
51
+ ruby 0.000000 0.000000 0.000000 ( 0.001067)
52
+ -------------------------------------- total: 0.000000sec
53
+
54
+ user system total real
55
+ c-extension 0.000000 0.000000 0.000000 ( 0.000019)
56
+ ruby 0.000000 0.000000 0.000000 ( 0.000731)
57
+
58
+ lenght of string: 5000
59
+ Rehearsal -----------------------------------------------
60
+ c-extension 0.000000 0.000000 0.000000 ( 0.000074)
61
+ ruby 0.000000 0.000000 0.000000 ( 0.006990)
62
+ -------------------------------------- total: 0.000000sec
63
+
64
+ user system total real
65
+ c-extension 0.000000 0.000000 0.000000 ( 0.000059)
66
+ ruby 0.000000 0.000000 0.000000 ( 0.003058)
67
+
68
+ lenght of string: 50000
69
+ Rehearsal -----------------------------------------------
70
+ c-extension 0.000000 0.000000 0.000000 ( 0.000276)
71
+ ruby 0.030000 0.000000 0.030000 ( 0.022061)
72
+ -------------------------------------- total: 0.030000sec
73
+
74
+ user system total real
75
+ c-extension 0.000000 0.000000 0.000000 ( 0.000117)
76
+ ruby 0.010000 0.000000 0.010000 ( 0.014624)
77
+
78
+ lenght of string: 500000
79
+ Rehearsal -----------------------------------------------
80
+ c-extension 0.000000 0.000000 0.000000 ( 0.001346)
81
+ ruby 0.140000 0.000000 0.140000 ( 0.147500)
82
+ -------------------------------------- total: 0.140000sec
83
+
84
+ user system total real
85
+ c-extension 0.000000 0.000000 0.000000 ( 0.001188)
86
+ ruby 0.140000 0.000000 0.140000 ( 0.146642)
87
+
88
+ lenght of string: 5000000
89
+ Rehearsal -----------------------------------------------
90
+ c-extension 0.010000 0.000000 0.010000 ( 0.013171)
91
+ ruby 1.480000 0.010000 1.490000 ( 1.482893)
92
+ -------------------------------------- total: 1.500000sec
93
+
94
+ user system total real
95
+ c-extension 0.010000 0.000000 0.010000 ( 0.013098)
96
+ ruby 1.510000 0.000000 1.510000 ( 1.508361)
97
+
98
+ lenght of string: 50000000
99
+ Rehearsal -----------------------------------------------
100
+ c-extension 0.120000 0.020000 0.140000 ( 0.143160)
101
+ ruby 16.320000 0.020000 16.340000 ( 16.356332)
102
+ ------------------------------------- total: 16.480000sec
103
+
104
+ user system total real
105
+ c-extension 0.120000 0.010000 0.130000 ( 0.143203)
106
+ ruby 15.130000 0.050000 15.180000 ( 15.191924)
107
+
108
+ lenght of string: 500000000
109
+ Rehearsal -----------------------------------------------
110
+ c-extension 1.190000 0.200000 1.390000 ( 1.491211)
111
+ ruby 159.510000 0.210000 159.720000 (159.723059)
112
+ ------------------------------------ total: 161.110000sec
113
+
114
+ user system total real
115
+ c-extension 1.270000 0.200000 1.470000 ( 1.568321)
116
+ ruby 161.190000 0.250000 161.440000 (161.449839)
117
+
118
+ ```
119
+
42
120
  ## Development
43
121
 
44
122
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. For compile c extension run `rake compile`.
data/benchmark.rb ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kmp"
5
+
6
+ def compute_prefix(ptrn)
7
+ m = ptrn.size
8
+ prefix = Array.new m, 0
9
+ k = -1
10
+ prefix[0] = -1
11
+ (m-1).times do |i|
12
+ i = i + 1
13
+ while k>-1 && ptrn[k+1] != ptrn[i] do
14
+ k = prefix[k];
15
+ end
16
+ if ptrn[k+1] == ptrn[i]
17
+ k = k + 1
18
+ end
19
+ prefix[i] = k
20
+ end
21
+ prefix
22
+ end
23
+
24
+ def kmp_ruby(txt, ptrn)
25
+ prefix = compute_prefix(ptrn)
26
+ n = txt.size
27
+ m = ptrn.size
28
+ pos = []
29
+
30
+ q = -1
31
+ (n).times do |i|
32
+ while(q>-1 && ptrn[q+1]!=txt[i]) do
33
+ q = prefix[q]
34
+ end
35
+ if ptrn[q+1] == txt[i]
36
+ q = q + 1
37
+ end
38
+ if q == (m-1)
39
+ pos << (i-m+1)
40
+ q = prefix[q]
41
+ end
42
+ end
43
+ return pos
44
+ end
45
+
46
+ require 'benchmark'
47
+
48
+ n = 1
49
+ 7.times do |t|
50
+ n = n * 10;
51
+ txt = ''
52
+ (n).times{txt << 'xpyyubzabcabcabcabcabcabcabcabcabcabcxyzabukxpyksl'}
53
+ puts "lenght of string: #{txt.size}"
54
+ a = Kmp::String.new(txt);
55
+ Benchmark.bmbm do |x|
56
+ x.report("c-extension") { a.match 'abcabcabcabcabcabc' }
57
+ x.report("ruby") { kmp_ruby(txt, 'abcabcabcabcabcabc') }
58
+ end
59
+ puts ""
60
+ end
data/benchmark.txt ADDED
@@ -0,0 +1,70 @@
1
+ lenght of string: 500
2
+ Rehearsal -----------------------------------------------
3
+ c-extension 0.000000 0.000000 0.000000 ( 0.000028)
4
+ ruby 0.000000 0.000000 0.000000 ( 0.001067)
5
+ -------------------------------------- total: 0.000000sec
6
+
7
+ user system total real
8
+ c-extension 0.000000 0.000000 0.000000 ( 0.000019)
9
+ ruby 0.000000 0.000000 0.000000 ( 0.000731)
10
+
11
+ lenght of string: 5000
12
+ Rehearsal -----------------------------------------------
13
+ c-extension 0.000000 0.000000 0.000000 ( 0.000074)
14
+ ruby 0.000000 0.000000 0.000000 ( 0.006990)
15
+ -------------------------------------- total: 0.000000sec
16
+
17
+ user system total real
18
+ c-extension 0.000000 0.000000 0.000000 ( 0.000059)
19
+ ruby 0.000000 0.000000 0.000000 ( 0.003058)
20
+
21
+ lenght of string: 50000
22
+ Rehearsal -----------------------------------------------
23
+ c-extension 0.000000 0.000000 0.000000 ( 0.000276)
24
+ ruby 0.030000 0.000000 0.030000 ( 0.022061)
25
+ -------------------------------------- total: 0.030000sec
26
+
27
+ user system total real
28
+ c-extension 0.000000 0.000000 0.000000 ( 0.000117)
29
+ ruby 0.010000 0.000000 0.010000 ( 0.014624)
30
+
31
+ lenght of string: 500000
32
+ Rehearsal -----------------------------------------------
33
+ c-extension 0.000000 0.000000 0.000000 ( 0.001346)
34
+ ruby 0.140000 0.000000 0.140000 ( 0.147500)
35
+ -------------------------------------- total: 0.140000sec
36
+
37
+ user system total real
38
+ c-extension 0.000000 0.000000 0.000000 ( 0.001188)
39
+ ruby 0.140000 0.000000 0.140000 ( 0.146642)
40
+
41
+ lenght of string: 5000000
42
+ Rehearsal -----------------------------------------------
43
+ c-extension 0.010000 0.000000 0.010000 ( 0.013171)
44
+ ruby 1.480000 0.010000 1.490000 ( 1.482893)
45
+ -------------------------------------- total: 1.500000sec
46
+
47
+ user system total real
48
+ c-extension 0.010000 0.000000 0.010000 ( 0.013098)
49
+ ruby 1.510000 0.000000 1.510000 ( 1.508361)
50
+
51
+ lenght of string: 50000000
52
+ Rehearsal -----------------------------------------------
53
+ c-extension 0.120000 0.020000 0.140000 ( 0.143160)
54
+ ruby 16.320000 0.020000 16.340000 ( 16.356332)
55
+ ------------------------------------- total: 16.480000sec
56
+
57
+ user system total real
58
+ c-extension 0.120000 0.010000 0.130000 ( 0.143203)
59
+ ruby 15.130000 0.050000 15.180000 ( 15.191924)
60
+
61
+ lenght of string: 500000000
62
+ Rehearsal -----------------------------------------------
63
+ c-extension 1.190000 0.200000 1.390000 ( 1.491211)
64
+ ruby 159.510000 0.210000 159.720000 (159.723059)
65
+ ------------------------------------ total: 161.110000sec
66
+
67
+ user system total real
68
+ c-extension 1.270000 0.200000 1.470000 ( 1.568321)
69
+ ruby 161.190000 0.250000 161.440000 (161.449839)
70
+
data/ext/kmp/kmp_string.c CHANGED
@@ -27,7 +27,7 @@ static VALUE initialize(VALUE self, VALUE rb_string)
27
27
  Check_Type(rb_string, T_STRING);
28
28
  Data_Get_Struct(self, struct Str, str);
29
29
 
30
- str->ptr = calloc(RSTRING_LEN(rb_string) , sizeof(char));
30
+ str->ptr = calloc(RSTRING_LEN(rb_string) + 1 , sizeof(char));
31
31
  memcpy(str->ptr, StringValuePtr(rb_string), RSTRING_LEN(rb_string));
32
32
 
33
33
  rb_iv_set(self, "@str", rb_string);
@@ -36,15 +36,14 @@ static VALUE initialize(VALUE self, VALUE rb_string)
36
36
  return self;
37
37
  }
38
38
 
39
- static int* compute_prefix(char *str)
39
+ static int* compute_prefix(const char *str)
40
40
  {
41
41
  int len = strlen(str);
42
-
42
+ int k = -1;
43
43
  int * prefix;
44
- prefix = calloc(len+1, sizeof(int));
45
44
 
45
+ prefix = (int *) calloc(len+1, sizeof(int));
46
46
  prefix[0] = -1;
47
- int k = -1;
48
47
 
49
48
  for(int i=1; i<len; i++)
50
49
  {
@@ -62,20 +61,21 @@ static VALUE match(VALUE self, VALUE rb_str)
62
61
  char * str;
63
62
  char * ptrn;
64
63
  int * prefix;
64
+ int n,m,q;
65
65
 
66
66
  Data_Get_Struct(self, struct Str, obj);
67
- str = calloc(strlen(obj->ptr), sizeof(char));
67
+ str = calloc(strlen(obj->ptr) + 1, sizeof(char));
68
68
  strcpy(str, obj->ptr);
69
69
 
70
- ptrn = calloc(RSTRING_LEN(rb_str), sizeof(char));
70
+ ptrn = (char *) calloc(RSTRING_LEN(rb_str) + 1, sizeof(char));
71
71
  memcpy(ptrn, StringValuePtr(rb_str), RSTRING_LEN(rb_str));
72
72
 
73
73
  prefix = compute_prefix(ptrn);
74
74
 
75
- int n = strlen(str);
76
- int m = strlen(ptrn);
75
+ n = strlen(str);
76
+ m = strlen(ptrn);
77
77
 
78
- int q = -1;
78
+ q = -1;
79
79
  for(int i=0; i<n; i++)
80
80
  {
81
81
  while( q>-1 && ptrn[q+1]!=str[i] ) q = prefix[q];
data/lib/kmp/kmp.so CHANGED
Binary file
data/lib/kmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kmp
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tanvir hasan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-02 00:00:00.000000000 Z
11
+ date: 2018-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,7 +108,8 @@ files:
108
108
  - LICENSE.txt
109
109
  - README.md
110
110
  - Rakefile
111
- - banch_mark.rb
111
+ - benchmark.rb
112
+ - benchmark.txt
112
113
  - bin/console
113
114
  - bin/setup
114
115
  - ext/kmp/extconf.rb
data/banch_mark.rb DELETED
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "kmp"
5
-
6
- #(0...50).map { ('a'..'z').to_a[rand(26)] }.join
7
- txt = ''
8
- 10000.times{txt << 'abc'}
9
-
10
- t1 = Time.now
11
- a = Kmp::String.new txt
12
- b = a.match 'abcabcabcabcabcabc'
13
- puts Time.now - t1
14
- puts b.length
15
-
16
- t1 = Time.now
17
- b = txt.enum_for(:scan, /(?=abcabcabcabcabcabc)/).map { Regexp.last_match.offset(0).first }
18
- puts Time.now - t1
19
- puts b.size