Browse Source

Add a fast std_rand implementation + other enhancements

Yann Weber 2 years ago
parent
commit
5283207080
3 changed files with 48 additions and 27 deletions
  1. 0
    5
      p2.gp
  2. 6
    0
      runplot3d.sh
  3. 42
    22
      sadrand.py

+ 0
- 5
p2.gp View File

@@ -1,5 +0,0 @@
1
-#!/usr/bin/gnuplot -p
2
-splot \
3
- "/tmp/rnd3d.dat" using 1:2:3 w l lt rgb "green" t "std-rand" \
4
-,"/tmp/rnd3d.dat" using 1:2:4 w l lt rgb "blue" t "mod-rand" \
5
-,"/tmp/rnd3d.dat" using 1:2:5 w l lt rgb "red" t "prop-rand"

+ 6
- 0
runplot3d.sh View File

@@ -10,6 +10,12 @@ then
10 10
     exit 1
11 11
 fi
12 12
 
13
+if [ "$1" = "-h" ]
14
+then
15
+    usage
16
+    exit 0
17
+fi
18
+
13 19
 maxres=${1:-100}
14 20
 minres=${2:-90}
15 21
 iter_res=${3:-10000}

+ 42
- 22
sadrand.py View File

@@ -2,14 +2,11 @@
2 2
 
3 3
 import random
4 4
 import argparse
5
+import math
5 6
 import sys
6 7
 import warnings
7 8
 
8
-try:
9
-    from tqdm import tqdm
10
-except (NameError, ImportError):
11
-    warnings.warn("tqdm module not found, no progress bar")
12
-    tqdm = lambda it, **kwargs: iter(it)
9
+tqdm = lambda it, **kwargs: iter(it)
13 10
 
14 11
 def std_rand(args):
15 12
     result = [0 for _ in range(args.resolution)];
@@ -17,6 +14,17 @@ def std_rand(args):
17 14
         result[random.randint(0, args.resolution-1)] += 1
18 15
     return result
19 16
 
17
+def std_rand_fast(args):
18
+    result = [0 for _ in range(args.resolution)];
19
+    nbits = math.ceil(math.log2(args.resolution))
20
+    for _ in tqdm(range(args.iter), unit_scale=True, total=args.iter):
21
+        while True:
22
+            rnd = random.getrandbits(nbits)
23
+            if rnd < args.resolution:
24
+                break
25
+        result[rnd] += 1
26
+    return result
27
+
20 28
 def rnd_bytes(count, chunk_size=4096):
21 29
     to_read = count
22 30
     with open('/dev/urandom', 'br') as rfd:
@@ -36,27 +44,39 @@ def generic_rand(args, rnd_fun):
36 44
 mod_rand = lambda args: generic_rand(args,
37 45
                                  lambda rbyte: rbyte % args.resolution)
38 46
 prop_rand = lambda args: generic_rand(args,
39
-                                  lambda rbyte: (rbyte * (args.resolution)) // 256)
40
-
41
-parser = argparse.ArgumentParser();
42
-parser.add_argument('-i', '--iter', type=lambda v: int(v,0), default=0x100000);
43
-parser.add_argument('-r', '--resolution', type=lambda v: int(v,0), default=100);
44
-parser.add_argument('-c', '--chunk-size', type=int, default=4096);
45
-parser.add_argument('-R', '--relative', action="store_true", default=False)
47
+                                  lambda rbyte:(rbyte*(args.resolution)) // 256)
46 48
 
47
-args = parser.parse_args();
49
+if __name__ == "__main__":
50
+    parser = argparse.ArgumentParser();
51
+    parser.add_argument('-i', '--iter', type=lambda v: int(v,0),
52
+                        default=0x100000);
53
+    parser.add_argument('-r', '--resolution', type=lambda v: int(v,0),
54
+                        default=100);
55
+    parser.add_argument('-c', '--chunk-size', type=int, default=4096);
56
+    parser.add_argument('-R', '--relative', action="store_true",
57
+                        default=False);
58
+    parser.add_argument('-p', '--progress', action="store_true",
59
+                        default=False);
60
+    parser.add_argument('--std', action="store_true", default=False,
61
+                        help="Use random.randint instead of random.getrandbits")
48 62
 
63
+    args = parser.parse_args();
49 64
 
50
-methods = (std_rand, mod_rand, prop_rand)
51
-results = [method(args) for method in methods]
65
+    if args.progress:
66
+        try:
67
+            from tqdm import tqdm
68
+        except (NameError, ImportError):
69
+            warnings.warn("tqdm module not found, no progress bar")
52 70
 
53
-if args.relative:
54
-    for i, result in enumerate(results):
55
-        results[i] = [(r / args.iter) * args.resolution for r in result]
56
-    
71
+    methods = (std_rand if args.std else std_rand_fast, mod_rand, prop_rand)
72
+    results = [method(args) for method in methods]
57 73
 
58
-for i, res in enumerate(zip(*results)):
59 74
     if args.relative:
60
-        i = i / args.resolution
61
-    sys.stdout.write(str(i) + ' ' + (' '.join([str(r) for r in res]))+'\n')
75
+        for i, result in enumerate(results):
76
+            results[i] = [(r / args.iter) * args.resolution for r in result]
77
+
78
+    for i, res in enumerate(zip(*results)):
79
+        if args.relative:
80
+            i = i / args.resolution
81
+        sys.stdout.write(str(i) + ' ' + (' '.join([str(r) for r in res]))+'\n')
62 82
 

Loading…
Cancel
Save