michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "prio.h" michael@0: #include "prinrval.h" michael@0: #include "prmem.h" michael@0: #include michael@0: #include michael@0: michael@0: void michael@0: NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues, michael@0: double *meanResult, double *stdDevResult) michael@0: { michael@0: double mean = 0.0, var = 0.0, stdDev = 0.0; michael@0: if (n > 0.0 && sumOfValues >= 0) { michael@0: mean = sumOfValues / n; michael@0: double temp = (n * sumOfSquaredValues) - (sumOfValues * sumOfValues); michael@0: if (temp < 0.0 || n <= 1) michael@0: var = 0.0; michael@0: else michael@0: var = temp / (n * (n - 1)); michael@0: // for some reason, Windows says sqrt(0.0) is "-1.#J" (?!) so do this: michael@0: stdDev = var != 0.0 ? sqrt(var) : 0.0; michael@0: } michael@0: *meanResult = mean; michael@0: *stdDevResult = stdDev; michael@0: } michael@0: michael@0: int michael@0: Test(const char* filename, int32_t minSize, int32_t maxSize, michael@0: int32_t sizeIncrement, int32_t iterations) michael@0: { michael@0: fprintf(stdout, " size write: mean stddev iters total: mean stddev iters\n"); michael@0: for (int32_t size = minSize; size <= maxSize; size += sizeIncrement) { michael@0: // create a buffer of stuff to write michael@0: char* buf = (char*)PR_Malloc(size); michael@0: if (buf == nullptr) michael@0: return -1; michael@0: michael@0: // initialize it with a pattern michael@0: int32_t i; michael@0: char hex[] = "0123456789ABCDEF"; michael@0: for (i = 0; i < size; i++) { michael@0: buf[i] = hex[i & 0xF]; michael@0: } michael@0: michael@0: double writeCount = 0, writeRate = 0, writeRateSquared = 0; michael@0: double totalCount = 0, totalRate = 0, totalRateSquared = 0; michael@0: for (i = 0; i < iterations; i++) { michael@0: PRIntervalTime start = PR_IntervalNow(); michael@0: michael@0: char name[1024]; michael@0: sprintf(name, "%s_%d", filename, i); michael@0: PRFileDesc* fd = PR_Open(name, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664); michael@0: if (fd == nullptr) michael@0: return -1; michael@0: michael@0: PRIntervalTime writeStart = PR_IntervalNow(); michael@0: int32_t rv = PR_Write(fd, buf, size); michael@0: if (rv < 0) return rv; michael@0: if (rv != size) return -1; michael@0: PRIntervalTime writeStop = PR_IntervalNow(); michael@0: michael@0: PRStatus st = PR_Close(fd); michael@0: if (st == PR_FAILURE) return -1; michael@0: michael@0: PRIntervalTime stop = PR_IntervalNow(); michael@0: michael@0: PRIntervalTime writeTime = PR_IntervalToMilliseconds(writeStop - writeStart); michael@0: if (writeTime > 0) { michael@0: double wr = size / writeTime; michael@0: writeRate += wr; michael@0: writeRateSquared += wr * wr; michael@0: writeCount++; michael@0: } michael@0: michael@0: PRIntervalTime totalTime = PR_IntervalToMilliseconds(stop - start); michael@0: if (totalTime > 0) { michael@0: double t = size / totalTime; michael@0: totalRate += t; michael@0: totalRateSquared += t * t; michael@0: totalCount++; michael@0: } michael@0: } michael@0: michael@0: PR_Free(buf); michael@0: michael@0: double writeMean, writeStddev; michael@0: double totalMean, totalStddev; michael@0: NS_MeanAndStdDev(writeCount, writeRate, writeRateSquared, michael@0: &writeMean, &writeStddev); michael@0: NS_MeanAndStdDev(totalCount, totalRate, totalRateSquared, michael@0: &totalMean, &totalStddev); michael@0: fprintf(stdout, "%10d %10.2f %10.2f %10d %10.2f %10.2f %10d\n", michael@0: size, writeMean, writeStddev, (int32_t)writeCount, michael@0: totalMean, totalStddev, (int32_t)totalCount); michael@0: } michael@0: return 0; michael@0: } michael@0: michael@0: int michael@0: main(int argc, char* argv[]) michael@0: { michael@0: if (argc != 5) { michael@0: printf("usage: %s \n", argv[0]); michael@0: return -1; michael@0: } michael@0: Test("y:\\foo", michael@0: atoi(argv[1]) * 1024, michael@0: atoi(argv[2]) * 1024, michael@0: atoi(argv[3]) * 1024, michael@0: atoi(argv[4])); michael@0: return 0; michael@0: }