|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "prio.h" |
|
7 #include "prinrval.h" |
|
8 #include "prmem.h" |
|
9 #include <stdio.h> |
|
10 #include <math.h> |
|
11 |
|
12 void |
|
13 NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues, |
|
14 double *meanResult, double *stdDevResult) |
|
15 { |
|
16 double mean = 0.0, var = 0.0, stdDev = 0.0; |
|
17 if (n > 0.0 && sumOfValues >= 0) { |
|
18 mean = sumOfValues / n; |
|
19 double temp = (n * sumOfSquaredValues) - (sumOfValues * sumOfValues); |
|
20 if (temp < 0.0 || n <= 1) |
|
21 var = 0.0; |
|
22 else |
|
23 var = temp / (n * (n - 1)); |
|
24 // for some reason, Windows says sqrt(0.0) is "-1.#J" (?!) so do this: |
|
25 stdDev = var != 0.0 ? sqrt(var) : 0.0; |
|
26 } |
|
27 *meanResult = mean; |
|
28 *stdDevResult = stdDev; |
|
29 } |
|
30 |
|
31 int |
|
32 Test(const char* filename, int32_t minSize, int32_t maxSize, |
|
33 int32_t sizeIncrement, int32_t iterations) |
|
34 { |
|
35 fprintf(stdout, " size write: mean stddev iters total: mean stddev iters\n"); |
|
36 for (int32_t size = minSize; size <= maxSize; size += sizeIncrement) { |
|
37 // create a buffer of stuff to write |
|
38 char* buf = (char*)PR_Malloc(size); |
|
39 if (buf == nullptr) |
|
40 return -1; |
|
41 |
|
42 // initialize it with a pattern |
|
43 int32_t i; |
|
44 char hex[] = "0123456789ABCDEF"; |
|
45 for (i = 0; i < size; i++) { |
|
46 buf[i] = hex[i & 0xF]; |
|
47 } |
|
48 |
|
49 double writeCount = 0, writeRate = 0, writeRateSquared = 0; |
|
50 double totalCount = 0, totalRate = 0, totalRateSquared = 0; |
|
51 for (i = 0; i < iterations; i++) { |
|
52 PRIntervalTime start = PR_IntervalNow(); |
|
53 |
|
54 char name[1024]; |
|
55 sprintf(name, "%s_%d", filename, i); |
|
56 PRFileDesc* fd = PR_Open(name, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); |
|
57 if (fd == nullptr) |
|
58 return -1; |
|
59 |
|
60 PRIntervalTime writeStart = PR_IntervalNow(); |
|
61 int32_t rv = PR_Write(fd, buf, size); |
|
62 if (rv < 0) return rv; |
|
63 if (rv != size) return -1; |
|
64 PRIntervalTime writeStop = PR_IntervalNow(); |
|
65 |
|
66 PRStatus st = PR_Close(fd); |
|
67 if (st == PR_FAILURE) return -1; |
|
68 |
|
69 PRIntervalTime stop = PR_IntervalNow(); |
|
70 |
|
71 PRIntervalTime writeTime = PR_IntervalToMilliseconds(writeStop - writeStart); |
|
72 if (writeTime > 0) { |
|
73 double wr = size / writeTime; |
|
74 writeRate += wr; |
|
75 writeRateSquared += wr * wr; |
|
76 writeCount++; |
|
77 } |
|
78 |
|
79 PRIntervalTime totalTime = PR_IntervalToMilliseconds(stop - start); |
|
80 if (totalTime > 0) { |
|
81 double t = size / totalTime; |
|
82 totalRate += t; |
|
83 totalRateSquared += t * t; |
|
84 totalCount++; |
|
85 } |
|
86 } |
|
87 |
|
88 PR_Free(buf); |
|
89 |
|
90 double writeMean, writeStddev; |
|
91 double totalMean, totalStddev; |
|
92 NS_MeanAndStdDev(writeCount, writeRate, writeRateSquared, |
|
93 &writeMean, &writeStddev); |
|
94 NS_MeanAndStdDev(totalCount, totalRate, totalRateSquared, |
|
95 &totalMean, &totalStddev); |
|
96 fprintf(stdout, "%10d %10.2f %10.2f %10d %10.2f %10.2f %10d\n", |
|
97 size, writeMean, writeStddev, (int32_t)writeCount, |
|
98 totalMean, totalStddev, (int32_t)totalCount); |
|
99 } |
|
100 return 0; |
|
101 } |
|
102 |
|
103 int |
|
104 main(int argc, char* argv[]) |
|
105 { |
|
106 if (argc != 5) { |
|
107 printf("usage: %s <min buf size (K)> <max buf size (K)> <size increment (K)> <iterations>\n", argv[0]); |
|
108 return -1; |
|
109 } |
|
110 Test("y:\\foo", |
|
111 atoi(argv[1]) * 1024, |
|
112 atoi(argv[2]) * 1024, |
|
113 atoi(argv[3]) * 1024, |
|
114 atoi(argv[4])); |
|
115 return 0; |
|
116 } |