-
Notifications
You must be signed in to change notification settings - Fork 12
/
seeker.py
executable file
·93 lines (74 loc) · 2.17 KB
/
seeker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python
"""Usage: seeker.py /path/to/raw/device
Measures the possible number of seeks per second.
"""
# It should work on any Unix.
# It is based on the Linux specific seeker.c from:
# http://www.linuxinsight.com/how_fast_is_your_disk.html
import os
import sys
import time
import random
BLOCKSIZE = 512
SEEK_END = 2
def _get_size(input):
input.seek(0, SEEK_END)
size = input.tell()
if size != 0:
return size
# FreeBSD does not support SEEK_END on devices.
# We need to get the size by binary halving.
pos = 0
step = 2**40 # 1TB
while True:
pos += step
try:
input.seek(pos)
data = input.read(1)
except IOError, possible:
data = ""
if len(data) != 1:
if step == 1:
# Size is the possible position + 1.
return (pos - step) + 1
pos -= step
step = max(1, step // 2)
def _seek_randomly(dev, size, num_seeks):
num_blocks = size // BLOCKSIZE
for i in xrange(num_seeks):
block = random.randrange(num_blocks)
dev.seek(block * BLOCKSIZE)
data = dev.read(BLOCKSIZE)
assert len(data) == BLOCKSIZE
def _benchmark_seek(dev, size, num_seeks):
start = time.time()
_seek_randomly(dev, size, num_seeks)
end = time.time()
duration = end - start
if duration > 0:
rate = int(num_seeks/float(duration))
else:
rate = float("inf")
print "%s/%.2f = %s seeks/second" % (
num_seeks, duration, rate)
print "%.2f ms random access time" % (1000 * duration/float(num_seeks))
def main():
args = sys.argv[1:]
if len(args) != 1:
print >>sys.stderr, __doc__
sys.exit(1)
filename = args[0]
dev = open(filename)
size = _get_size(dev)
if size < BLOCKSIZE:
print >>sys.stderr, (
"too small file: %s bytes" % size)
sys.exit(1)
print "Benchmarking %s [%.2f GB]" % (filename, size/float(2**30))
random.seed()
base = 10
for power in xrange(1, 6):
num_seeks = base**power
_benchmark_seek(dev, size, num_seeks)
if __name__ == "__main__":
main()