pcg_random 0.1.2 → 0.1.3

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: 80bdb7b230ebe145ca36718ca2b5ce75927611d3
4
- data.tar.gz: f54e765d9d10ce35f10ad63f1cbaa0e8f120fc80
3
+ metadata.gz: e9d916ffcf05c6305989a4a440ad40a7b3b6143e
4
+ data.tar.gz: 8db0e0f2fb5feee3390d0503c56f60ad0c33ce22
5
5
  SHA512:
6
- metadata.gz: daf8fdc612fdfb584896480a5ccb5f416cad2b235bbd8f46155c568dcee6b35c911a13eb7fc1af6a7ae5be2b3bd448cbe9f99506b06a17fa05403f5baa4ebc02
7
- data.tar.gz: 84057b096b179ffe467e470ba42ac35f84c626edf6c006f108aa9643f0e7b1e525d807a29683774be6e887844205499c7dab06aed3140c5e9f56477ebccbbff9
6
+ metadata.gz: 8074251b1e55a97ede7e8d34e815067f5032908c809d6cf26c578a9c55abb4974bf1d071796396d4ef430cd02802c89763d1dd289a9dbe6945bcc373decb2672
7
+ data.tar.gz: 8a0d123279a6973c28b4a10f33f42f58deac929fa37d1931067e20c34cd7b2b510ad16755d3b2cf3a8ebad8e0bc8c638de1aa83eb9f4529268c113e37db951e4
data/.gitignore CHANGED
@@ -19,7 +19,7 @@
19
19
  *.log
20
20
 
21
21
  # Github commit messages
22
- .gitmsg
22
+ gitmsg.md
23
23
 
24
24
  # Benchmark code till I find an alternative way that doesn't piss off
25
25
  # rake-compiler
data/Rakefile CHANGED
@@ -13,8 +13,4 @@ end
13
13
 
14
14
  task :cc => [:clean, :compile]
15
15
 
16
- task :default => [:clobber, :compile, :spec]
17
-
18
- task :bench do
19
- PCGBench.press
20
- end
16
+ task :default => [:clobber, :compile, :spec]
@@ -0,0 +1,39 @@
1
+ require 'benchmark'
2
+ require 'pcg_random'
3
+
4
+
5
+ # Benchmark of Random.new_seed vs PCGRandom.new_seed
6
+ # ==================================================
7
+ #
8
+ # Benchmark created around: 2016-03-20 14:28:07 +0000
9
+ #
10
+ # Running for: 100000 iterations
11
+ #
12
+ # Rehearsal ------------------------------------------------------
13
+ # Random.new_seed 0.110000 1.030000 1.140000 ( 1.135205)
14
+ # PCGRandom.new_seed 0.090000 1.060000 1.150000 ( 1.157619)
15
+ # --------------------------------------------- total: 2.290000sec
16
+ #
17
+ # user system total real
18
+ # Random.new_seed 0.090000 1.250000 1.340000 ( 1.348947)
19
+ # PCGRandom.new_seed 0.150000 1.000000 1.150000 ( 1.146167)
20
+
21
+
22
+ Iterations = 100_000
23
+
24
+ puts "Benchmark of Random.new_seed vs PCGRandom.new_seed"
25
+ puts "=================================================="
26
+ puts ""
27
+ puts "Benchmark created around: #{Time.now}"
28
+ puts ""
29
+ puts "Running for: #{Iterations} iterations"
30
+ puts ""
31
+ Benchmark.bmbm do |bench|
32
+ bench.report("Random.new_seed") do
33
+ Iterations.times {Random.new_seed}
34
+ end
35
+
36
+ bench.report("PCGRandom.new_seed") do
37
+ Iterations.times {PCGRandom.new_seed}
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require 'benchmark'
2
+ require 'pcg_random'
3
+
4
+
5
+ # Benchmark of Random.raw_seed(16) vs PCGRandom.raw_seed(16)
6
+ # ==================================================
7
+ #
8
+ # Benchmark created around: 2016-03-20 14:34:40 +0000
9
+ #
10
+ # Running for: 100000 iterations
11
+ #
12
+ # Rehearsal ----------------------------------------------------------
13
+ # Random.raw_seed(16) 0.060000 1.110000 1.170000 ( 1.173924)
14
+ # PCGRandom.raw_seed(16) 0.060000 1.110000 1.170000 ( 1.175782)
15
+ # ------------------------------------------------- total: 2.340000sec
16
+ #
17
+ # user system total real
18
+ # Random.raw_seed(16) 0.060000 1.230000 1.290000 ( 1.292141)
19
+ # PCGRandom.raw_seed(16) 0.080000 1.100000 1.180000 ( 1.189046)
20
+
21
+
22
+
23
+ Iterations = 100_000
24
+ SeedSize = 16
25
+ puts "Benchmark of Random.raw_seed(#{SeedSize}) vs PCGRandom.raw_seed(#{SeedSize})"
26
+ puts "=================================================="
27
+ puts ""
28
+ puts "Benchmark created around: #{Time.now}"
29
+ puts ""
30
+ puts "Running for: #{Iterations} iterations"
31
+ puts ""
32
+ Benchmark.bmbm do |bench|
33
+ bench.report("Random.raw_seed(#{SeedSize})") do
34
+ Iterations.times {Random.raw_seed SeedSize}
35
+ end
36
+
37
+ bench.report("PCGRandom.raw_seed(#{SeedSize})") do
38
+ Iterations.times {PCGRandom.raw_seed SeedSize}
39
+ end
40
+ end
@@ -61,17 +61,21 @@
61
61
 
62
62
  #if HAVE_DEV_RANDOM
63
63
  /* entropy_getbytes(dest, size):
64
- * Use /dev/random to get some external entropy for seeding purposes.
64
+ * Use /dev/urandom to get some external entropy for seeding purposes.
65
65
  *
66
66
  * Note:
67
- * If reading /dev/random fails (which ought to never happen), it returns
67
+ * If reading /dev/urandom fails (which ought to never happen), it returns
68
68
  * false, otherwise it returns true. If it fails, you could instead call
69
69
  * fallback_entropy_getbytes which always succeeds.
70
+ * Note2:
71
+ * This version is an edited copy of the original entropy.c used in pcg-c
72
+ * It uses /dev/urandom instead of /dev/random
73
+ * (Read: http://www.2uo.de/myths-about-urandom/)
70
74
  */
71
75
 
72
76
  bool entropy_getbytes(void* dest, size_t size)
73
77
  {
74
- int fd = open("/dev/random", O_RDONLY);
78
+ int fd = open("/dev/urandom", O_RDONLY);
75
79
  if (fd < 0)
76
80
  return false;
77
81
  int sz = read(fd, dest, size);
@@ -88,7 +92,7 @@ bool entropy_getbytes(void* dest, size_t size)
88
92
  #endif
89
93
 
90
94
  /* fallback_entropy_getbytes(dest, size):
91
- * Works like the /dev/random version above, but avoids using /dev/random.
95
+ * Works like the /dev/urandom version above, but avoids using /dev/random.
92
96
  * Instead, it uses a private RNG (so that repeated calls will return
93
97
  * different seeds). Makes no attempt at cryptographic security.
94
98
  */
@@ -1,6 +1,7 @@
1
1
  #include <ruby.h>
2
2
  #include <pcg_variants.h>
3
3
  #include <stdbool.h>
4
+ #include <stdint.h>
4
5
 
5
6
  #include "entropy.h"
6
7
  #include "rb_constants.h"
@@ -8,15 +9,14 @@
8
9
 
9
10
  static VALUE pcg_new_seed_bytestr(unsigned long seed_size);
10
11
  static VALUE pcg_raw_seed_bytestr(size_t size);
11
- static VALUE pcg_rb_unpack_str_uint(VALUE str);
12
12
 
13
13
  /*
14
- * Returns a n-bit integer that stores the seed value used to seed the
14
+ * Returns a n-byte integer that stores the seed value used to seed the
15
15
  * initial state and sequence for the PCG generator.
16
16
  * If no parameters are supplied it default to a 128-bit seed size
17
17
  *
18
18
  * @param size Number of bytes (EVEN!) that the generated seed must contain.
19
- * Defaults to 16 Bytes = 128 bits
19
+ * Defaults to 16 Bytes (uint8_t) = 128 bits
20
20
  *
21
21
  * @raise ArgumentError if size is not even
22
22
  */
@@ -28,7 +28,7 @@ pcg_func_new_seed(int argc, VALUE *argv, VALUE self)
28
28
 
29
29
  if(argc == 0)
30
30
  {
31
- return pcg_new_seed_bytestr(2 * sizeof(uint64_t));
31
+ return pcg_new_seed_bytestr(16 * sizeof(uint8_t));
32
32
  }
33
33
 
34
34
  rb_scan_args(argc, argv, "01", &seed_size);
@@ -40,7 +40,7 @@ pcg_func_new_seed(int argc, VALUE *argv, VALUE self)
40
40
  {
41
41
  rb_raise(rb_eArgError, "Seed size must be even! Found %lu", n);
42
42
  }
43
- return pcg_new_seed_bytestr(n * sizeof(char));
43
+ return pcg_new_seed_bytestr(n * sizeof(uint8_t));
44
44
  }
45
45
 
46
46
  /*
@@ -67,37 +67,12 @@ bool
67
67
  pcg_func_entropy_getbytes(void *dest, size_t size)
68
68
  {
69
69
  // Get random bytes from /dev/random or a fallback source
70
- return entropy_getbytes(dest, size);
71
- }
72
-
73
- /*
74
- * Internal - Unpacks a string `str` wuth String#unpack
75
- */
76
- static VALUE
77
- pcg_rb_unpack_str_uint(VALUE str)
78
- {
79
- VALUE ary, result, current, base;
80
- unsigned long len;
81
-
82
- // This would be an array of 8 bit fixnums, effectively representing it in
83
- // base-256
84
- ary = rb_funcall(str, rb_intern("unpack"), 1, rb_str_new2("C*\0"));
85
- len = RARRAY_LEN(ary);
86
-
87
- base = INT2FIX(256);
88
- result = pcg_rb_zero;
89
-
90
- // First entry in array corresponds to highest significance
91
- for(int i = 0; i < len; ++i)
70
+ if(!entropy_getbytes(dest, size))
92
71
  {
93
- current = rb_ary_entry(ary, i);
94
- // Maybe optimize the below code based on on TYPE(result) later ?
95
- // Currently this doesnt utilize the C-API a effectively
96
- result = rb_funcall(result, pcg_rb_plus, 1, current);
97
- result = rb_funcall(result, pcg_rb_mul, 1 , base);
72
+ fallback_entropy_getbytes(dest, size);
73
+ return true;
98
74
  }
99
-
100
- return result;
75
+ return true;
101
76
  }
102
77
 
103
78
  /*
@@ -107,9 +82,13 @@ pcg_rb_unpack_str_uint(VALUE str)
107
82
  static VALUE
108
83
  pcg_raw_seed_bytestr(size_t size)
109
84
  {
110
- char *bytestr = (char *) malloc(size + 1);
111
85
  VALUE result;
112
-
86
+ char *bytestr = (char *) malloc(size + 1);
87
+ if(bytestr == NULL)
88
+ {
89
+ rb_raise(rb_eNoMemError,
90
+ "Could not malloc enough space for %lu-byte seed!", size);
91
+ }
113
92
  memset(bytestr, 0, size + 1);
114
93
  pcg_func_entropy_getbytes((void *)bytestr, size);
115
94
 
@@ -127,8 +106,35 @@ pcg_raw_seed_bytestr(size_t size)
127
106
  static VALUE
128
107
  pcg_new_seed_bytestr(unsigned long seed_size)
129
108
  {
130
- VALUE seed_bytes_str;
131
- seed_bytes_str = pcg_raw_seed_bytestr(seed_size);
132
- return pcg_rb_unpack_str_uint(seed_bytes_str);
109
+ VALUE result;
110
+ uint8_t *bytes = (uint8_t *) malloc(seed_size * sizeof(uint8_t));
111
+ unsigned long *buf = (unsigned long *) malloc(seed_size * sizeof(unsigned long));
112
+
113
+ if(bytes == NULL || buf == NULL)
114
+ {
115
+ rb_raise(rb_eNoMemError, "Could not malloc enough memory!");
116
+ }
117
+
118
+ memset(bytes, 0, seed_size);
119
+
120
+ if(!pcg_func_entropy_getbytes((void *)bytes, seed_size))
121
+ {
122
+ rb_raise(rb_eRuntimeError, "Unable to generate seed!");
123
+ }
124
+
125
+ // Populate an array of longs to feed to rb_big_unpack()
126
+ for(int i = 0; i < seed_size; ++i)
127
+ {
128
+ buf[i] = (unsigned long) bytes[i];
129
+ }
130
+
131
+ // Inspired from ruby's very own random.c
132
+ // see: http://rxr.whitequark.org/mri/source/random.c#493
133
+ // Also: http://rxr.whitequark.org/mri/source/random.c#443
134
+ result = rb_big_unpack(buf, seed_size);
135
+
136
+ free(bytes);
137
+ free(buf);
138
+
139
+ return result;
133
140
  }
134
-
@@ -1,3 +1,3 @@
1
1
  class PCGRandom
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pcg_random
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vaibhav Yenamandra
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-19 00:00:00.000000000 Z
11
+ date: 2016-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -96,6 +96,8 @@ files:
96
96
  - LICENSE.txt
97
97
  - README.md
98
98
  - Rakefile
99
+ - benchmarks/new_seed_bench.rb
100
+ - benchmarks/raw_seed_bench.rb
99
101
  - bin/console
100
102
  - bin/setup
101
103
  - ext/pcg_random/entropy.c