sieve 0.1.1 → 0.1.2
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.
- data/README.markdown +43 -27
- data/Rakefile +5 -1
- data/ext/sieve/sieve.c +10 -8
- data/ext/sieve/sieve.h +6 -0
- data/features/sieve.feature +5 -0
- data/lib/sieve.rb +1 -1
- metadata +2 -5
data/README.markdown
CHANGED
@@ -12,13 +12,18 @@ Install with Rubygems:
|
|
12
12
|
|
13
13
|
A method is added to the Numeric class.
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
>> require "sieve"
|
16
|
+
=> true
|
17
|
+
>> 5.sieve
|
18
|
+
=> [2, 3, 5]
|
19
|
+
>> 100.sieve
|
20
|
+
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
|
17
21
|
|
18
22
|
## Benchmarks
|
19
23
|
|
20
24
|
This benchmark loops through a handful of numbers 0 to 1 million in steps of
|
21
|
-
100000 and runs a sieve on each number.
|
25
|
+
100000 and runs a sieve on each number. I also include benchmarks for running
|
26
|
+
the sieve against 10 million and 100 million.
|
22
27
|
|
23
28
|
The sieve method itself looks like this:
|
24
29
|
|
@@ -37,30 +42,41 @@ As far as I know, this is the most optimized pure Ruby sieve written.
|
|
37
42
|
|
38
43
|
The benchmarks were run on a 2.8GHz Intel Core 2 Duo MacBook Pro with 8 GB memory.
|
39
44
|
|
40
|
-
ruby 1.8.6 (2010-02-05 patchlevel 399) [i686-darwin10.4.0]
|
41
|
-
|
42
|
-
|
43
|
-
sieve method
|
44
|
-
Numeric#sieve
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
sieve
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
sieve
|
63
|
-
|
45
|
+
### ruby 1.8.6 (2010-02-05 patchlevel 399) [i686-darwin10.4.0]
|
46
|
+
|
47
|
+
user system total real
|
48
|
+
sieve method 4.450000 0.060000 4.510000 ( 4.526172)
|
49
|
+
Numeric#sieve 0.040000 0.000000 0.040000 ( 0.046676)
|
50
|
+
sieve 10_000_000 8.780000 0.120000 8.900000 ( 9.010072)
|
51
|
+
10_000_000.sieve 0.080000 0.000000 0.080000 ( 0.084518)
|
52
|
+
100_000_000.sieve 2.050000 0.050000 2.100000 ( 2.128403)
|
53
|
+
|
54
|
+
### ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10.4.0]
|
55
|
+
|
56
|
+
user system total real
|
57
|
+
sieve method 4.460000 0.060000 4.520000 ( 4.522069)
|
58
|
+
Numeric#sieve 0.040000 0.000000 0.040000 ( 0.046349)
|
59
|
+
sieve 10_000_000 8.820000 0.120000 8.940000 ( 8.955888)
|
60
|
+
10_000_000.sieve 0.080000 0.010000 0.090000 ( 0.083030)
|
61
|
+
100_000_000.sieve 2.040000 0.040000 2.080000 ( 2.100103)
|
62
|
+
|
63
|
+
### ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.0], MBARI 0x6770, Ruby Enterprise Edition 2010.02
|
64
|
+
|
65
|
+
user system total real
|
66
|
+
sieve method 4.610000 0.090000 4.700000 ( 4.730966)
|
67
|
+
Numeric#sieve 0.050000 0.010000 0.060000 ( 0.046442)
|
68
|
+
sieve 10_000_000 8.640000 0.060000 8.700000 ( 8.731662)
|
69
|
+
10_000_000.sieve 0.100000 0.000000 0.100000 ( 0.104731)
|
70
|
+
100_000_000.sieve 2.250000 0.050000 2.300000 ( 2.303147)
|
71
|
+
|
72
|
+
### ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
73
|
+
|
74
|
+
user system total real
|
75
|
+
sieve method 2.410000 0.060000 2.470000 ( 2.468430)
|
76
|
+
Numeric#sieve 0.050000 0.000000 0.050000 ( 0.049053)
|
77
|
+
sieve 10_000_000 4.770000 0.110000 4.880000 ( 4.888397)
|
78
|
+
10_000_000.sieve 0.080000 0.000000 0.080000 ( 0.098229)
|
79
|
+
100_000_000.sieve 2.090000 0.040000 2.130000 ( 2.137024)
|
64
80
|
|
65
81
|
## Author
|
66
82
|
|
data/Rakefile
CHANGED
@@ -34,7 +34,7 @@ task(:benchmark => :build) do
|
|
34
34
|
|
35
35
|
Benchmark.bmbm(15) do |benchmark|
|
36
36
|
range = (0..1000000)
|
37
|
-
step =
|
37
|
+
step = 100000
|
38
38
|
|
39
39
|
benchmark.report("sieve method") do
|
40
40
|
range.step(step) do |i|
|
@@ -55,5 +55,9 @@ task(:benchmark => :build) do
|
|
55
55
|
benchmark.report("10_000_000.sieve") do
|
56
56
|
10_000_000.sieve
|
57
57
|
end
|
58
|
+
|
59
|
+
benchmark.report("100_000_000.sieve") do
|
60
|
+
100_000_000.sieve
|
61
|
+
end
|
58
62
|
end
|
59
63
|
end
|
data/ext/sieve/sieve.c
CHANGED
@@ -12,37 +12,39 @@ void Init_sieve() {
|
|
12
12
|
static VALUE sieve(const VALUE self) {
|
13
13
|
if(NUM2LONG(self) < 2) { return Qnil; }
|
14
14
|
long number = NUM2LONG(self) + 1;
|
15
|
-
short* numbers = malloc(number * sizeof(short));
|
16
15
|
|
17
|
-
|
16
|
+
char* results = malloc((long)(number/8));
|
17
|
+
|
18
|
+
if(results == NULL) {
|
18
19
|
rb_raise(rb_eNoMemError, "Can't allocate enough memory.");
|
19
20
|
}
|
20
21
|
|
21
|
-
|
22
|
+
CLEARBIT(results, 0);
|
23
|
+
CLEARBIT(results, 1);
|
22
24
|
long i;
|
23
|
-
for(i = 2; i < number; i++) {
|
25
|
+
for(i = 2; i < number; i++) { SETBIT(results, i); }
|
24
26
|
|
25
27
|
long current_square;
|
26
28
|
for(i = 0; i < number; i++) {
|
27
|
-
if(
|
29
|
+
if(BITNOTSET(results, i)) { continue; }
|
28
30
|
|
29
31
|
current_square = powl(i, 2);
|
30
32
|
if(current_square > number) { break; }
|
31
33
|
|
32
34
|
long n;
|
33
35
|
for(n = current_square; n < number; n += i) {
|
34
|
-
|
36
|
+
CLEARBIT(results, n);
|
35
37
|
}
|
36
38
|
}
|
37
39
|
|
38
40
|
VALUE primes_array = rb_ary_new();
|
39
41
|
for(i = 0; i < number; i++) {
|
40
|
-
if(
|
42
|
+
if(BITSET(results, i)) {
|
41
43
|
rb_ary_push(primes_array, LONG2FIX(i));
|
42
44
|
}
|
43
45
|
}
|
44
46
|
|
45
|
-
free(
|
47
|
+
free(results);
|
46
48
|
|
47
49
|
return primes_array;
|
48
50
|
}
|
data/ext/sieve/sieve.h
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
#ifndef __sieve_h__
|
2
2
|
#define __sieve_h__
|
3
|
+
|
4
|
+
#define BITSET(x,i) ((x)[(i)>>3] & (1<<((i)&7))) != 0
|
5
|
+
#define BITNOTSET(x,i) ((x)[(i)>>3] & (1<<((i)&7))) == 0
|
6
|
+
#define SETBIT(x,i) ((x)[(i)>>3] |= (1<<((i)&7)))
|
7
|
+
#define CLEARBIT(x,i) ((x)[(i)>>3] &= (1<<((i)&7))^0xFF)
|
8
|
+
|
3
9
|
static VALUE sieve(VALUE);
|
4
10
|
#endif
|
data/features/sieve.feature
CHANGED
@@ -17,6 +17,11 @@ Feature: Sieve of Eratosthenes
|
|
17
17
|
| 3 | 2,3 |
|
18
18
|
| 4 | 2,3 |
|
19
19
|
| 5 | 2,3,5 |
|
20
|
+
| 8 | 2,3,5,7 |
|
21
|
+
| 9 | 2,3,5,7 |
|
22
|
+
| 15 | 2,3,5,7,11,13 |
|
23
|
+
| 16 | 2,3,5,7,11,13 |
|
24
|
+
| 17 | 2,3,5,7,11,13,17 |
|
20
25
|
| 19 | 2,3,5,7,11,13,17,19 |
|
21
26
|
| 20 | 2,3,5,7,11,13,17,19 |
|
22
27
|
| 29 | 2,3,5,7,11,13,17,19,23,29 |
|
data/lib/sieve.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sieve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 25
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
8
|
+
- 2
|
9
|
+
version: 0.1.2
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Josh Clayton
|
@@ -55,7 +54,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
54
|
requirements:
|
56
55
|
- - ">="
|
57
56
|
- !ruby/object:Gem::Version
|
58
|
-
hash: 3
|
59
57
|
segments:
|
60
58
|
- 0
|
61
59
|
version: "0"
|
@@ -64,7 +62,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
62
|
requirements:
|
65
63
|
- - ">="
|
66
64
|
- !ruby/object:Gem::Version
|
67
|
-
hash: 3
|
68
65
|
segments:
|
69
66
|
- 0
|
70
67
|
version: "0"
|