Skip to content

Instantly share code, notes, and snippets.

@boukeversteegh
Last active September 23, 2020 17:52
Show Gist options
  • Save boukeversteegh/c2caf353640a280084afed9d27f5fbb1 to your computer and use it in GitHub Desktop.
Save boukeversteegh/c2caf353640a280084afed9d27f5fbb1 to your computer and use it in GitHub Desktop.
Dart reading files (sync/async) performance test
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
const KB = 1024;
const MB = 1024 * KB;
const GB = 1024 * MB;
const sizes = {'B': 1, 'KB': KB, 'MB': MB, 'GB': GB};
const blockSize = 16 * MB;
int check = 0xFF;
/// Write a file:
/// dart readfiletest.dart write 1 GB
///
/// Read it in different ways and print checksum:
/// dart readfiletest.dart read 1 GB sync
/// dart readfiletest.dart read 1 GB sync2
/// dart readfiletest.dart read 1 GB async
/// dart readfiletest.dart read 1 GB async2
Future<void> main(args) async {
final time = Stopwatch()..start();
var sizeCounter = int.parse(args[1]);
var sizeUnit = args[2];
final file = File('$sizeCounter$sizeUnit.bin');
print(file.path);
final size = sizeCounter * sizes[sizeUnit];
if (args[0] == 'write') {
print('writing');
writeFile(file, size);
} else {
print('reading');
switch (args[3]) {
case 'sync':
syncReadTest(file, size);
break;
case 'sync2':
syncReadIntoTest(file, size);
break;
case 'async':
await asyncReadTest(file, size);
break;
case 'async2':
await asyncReadIntoTest(file, size);
break;
case 'stream':
print('! ignoring block size');
await asyncReadStreamTest(file, size);
break;
}
}
var seconds = (time.elapsedMilliseconds / 1000);
print('Checksum: $check');
print('$seconds seconds, ${(size / MB) ~/ seconds} MB/s');
}
void writeFile(File file, int length) {
final handle = file.openSync(mode: FileMode.write);
final random = Random();
var total = 0;
var block = Uint8List(blockSize);
do {
total += blockSize;
for (var i = 0; i < blockSize; i++) {
var byte = random.nextInt(255);
block[i] = byte;
check ^= byte;
}
handle.writeFromSync(block);
} while (total < length);
}
void syncReadTest(File file, int length) {
final handle = file.openSync();
var total = 0;
var result = Uint8List(blockSize);
do {
total += blockSize;
result = handle.readSync(blockSize);
for (var i = 0; i < blockSize; i++) {
check ^= result[i];
}
} while (total < length);
}
void syncReadIntoTest(File file, int length) {
final handle = file.openSync();
var total = 0;
var block = Uint8List(blockSize);
do {
total += blockSize;
handle.readIntoSync(block);
for (var i = 0; i < blockSize; i++) {
check ^= block[i];
}
} while (total < length);
}
void asyncReadTest(File file, int length) async {
final handle = file.openSync();
var total = 0;
do {
total += blockSize;
await handle.read(blockSize).then((Uint8List result) {
for (var i = 0; i < blockSize; i++) {
check ^= result[i];
}
});
} while (total < length);
}
void asyncReadIntoTest(File file, int length) async {
final handle = file.openSync();
var total = 0;
var block = Uint8List(blockSize);
do {
total += blockSize;
await handle.readInto(block).then((n) {
for (var i = 0; i < n; i++) {
check ^= block[i];
}
});
} while (total < length);
}
void asyncReadStreamTest(File file, int length) async {
final stream = file.openRead();
var total = 0;
check = await stream.takeWhile((_) => total < length).fold(check,
(previousCheck, List<int> block) {
final l = block.length;
for (var i = 0; i < min(length - total, l); i++) {
previousCheck ^= block[i];
}
total += l;
return previousCheck;
});
print(check);
}
#include <iostream>
#include <fstream>
#include <chrono>
using namespace std::chrono;
using namespace std;
const int KB = 1024;
const int MB = 1024 * KB;
const int GB = 1024 * MB;
int main() {
auto start = high_resolution_clock::now();
string path = R"(1GB.bin)";
ifstream file(path, ios::in | ios::binary);
int check = 0xff;
char *block;
const unsigned int blockSize = 64 * KB;
const unsigned int size = 1 * GB;
block = new char[blockSize];
int total = 0;
if (file.is_open()) {
int i;
while (total < size) {
file.read(block, blockSize);
for (i = 0; i < blockSize; ++i) {
check ^= block[i];
}
total += blockSize;
}
file.close();
}
auto stop = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(stop - start);
cout << duration.count() << "milliseconds" << endl;
cout << ((1000u * (size / MB)) / duration.count()) << "MByte/s" << endl;
cout << check;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment