pcg_random 0.1.2 → 0.1.3

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.
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