Last active
February 14, 2019 01:10
-
-
Save rvprasad/3f7e7aa101ff86fa3559d84d403ee565 to your computer and use it in GitHub Desktop.
Measure throughput of default buffered I/O in different programming languages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <chrono> | |
#include <fstream> | |
#include <iostream> | |
using namespace std; | |
int k = 256; | |
int numOfNums = k * 1024 * 1024; | |
int reps = 6; | |
void writeUsingFile(string fileName) { | |
ofstream writer(fileName, ios_base::binary); | |
for (int i = 1; i <= numOfNums; ++i) { | |
writer << (uint8_t) (i & 0xff); | |
//writer.put(i & 0xff); // better option 1 | |
} | |
} | |
void readUsingFile(string fileName) { | |
ifstream reader(fileName, ios_base::binary); | |
uint8_t c; | |
//char c; // better option 1 | |
for (int i = 1; i <= numOfNums; ++i) { | |
reader >> c; | |
//reader.get(c); // better option 1 | |
} | |
remove(fileName.c_str()); | |
} | |
int main(int argc, char* argv[]) { | |
if (argc < 2) { | |
cerr << "Provide filename" << endl; | |
exit(-1); | |
} | |
string fileName(argv[1]); | |
remove(fileName.c_str()); | |
float read = 0; | |
float write = 0; | |
for (int i = 1; i <= reps; i++) { | |
auto time1 = chrono::system_clock::now(); | |
writeUsingFile(fileName); | |
auto time2 = chrono::system_clock::now(); | |
readUsingFile(fileName); | |
auto time3 = chrono::system_clock::now(); | |
auto tmp1 = numOfNums / 1024 / 1024 * 1e9; | |
auto diff1 = chrono::duration_cast<chrono::nanoseconds>(time3 - time2).count(); | |
auto readTime = tmp1 / diff1; | |
auto diff2 = chrono::duration_cast<chrono::nanoseconds>(time2 - time1).count(); | |
auto writeTime = tmp1 / diff2; | |
cout << readTime << ' ' << writeTime << endl; | |
if (i != 1) { | |
read += readTime; | |
write += writeTime; | |
} | |
} | |
int tmp1 = reps - 1; | |
cout << "Bytes: " << numOfNums / 1024 / 1024 \ | |
<< " MiB, ReadRate: " << read / tmp1 \ | |
<< "MB/s, WriteRate: " << write / tmp1 \ | |
<< " MB/s" << endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"os" | |
"time" | |
) | |
func writeUsingFile(fileName string, numOfNums int) { | |
file, _ := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY, 0600) | |
defer file.Close() | |
writer := bufio.NewWriter(file) | |
for i := 1; i <= numOfNums; i++ { | |
writer.WriteByte(byte(i & 0xff)) | |
} | |
} | |
func readUsingFile(fileName string, numOfNums int) { | |
file, _ := os.Open(fileName) | |
defer file.Close() | |
reader := bufio.NewReader(file) | |
for i := 1; i <= numOfNums; i++ { | |
reader.ReadByte() | |
} | |
os.Remove(fileName) | |
} | |
func main() { | |
if len(os.Args) < 2 { | |
fmt.Println("Provide filename") | |
os.Exit(-1) | |
} | |
k := 256 | |
numOfNums := k * 1024 * 1024 | |
fileName := os.Args[1] | |
reps := 6 | |
if os.Remove(fileName) != nil { | |
// ignore | |
} | |
var read float32 = 0.0 | |
var write float32 = 0.0 | |
for i := 1; i <= reps; i++ { | |
time1 := time.Now() | |
writeUsingFile(fileName, numOfNums) | |
time2 := time.Now() | |
readUsingFile(fileName, numOfNums) | |
time3 := time.Now() | |
tmp1 := float32(numOfNums/1024/1024) * 1e9 | |
diff1 := time3.Sub(time2) | |
readTime := tmp1 / float32(diff1) | |
diff2 := time2.Sub(time1) | |
writeTime := tmp1 / float32(diff2) | |
fmt.Println(readTime, writeTime) | |
if i != 1 { | |
read += float32(readTime) | |
write += float32(writeTime) | |
} | |
} | |
tmp1 := reps - 1 | |
fmt.Println("Bytes:", numOfNums/1024/1024, "MB, ReadRate:", | |
read/float32(tmp1), "MB/s, WriteRate:", write/float32(tmp1), "MB/s") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os, sys, time | |
if len(sys.argv) < 2: | |
print("Provide filename") | |
sys.exit(-1) | |
k = 256 | |
numOfNums = k * 1024 * 1024 | |
fileName = sys.argv[1] | |
reps = 6 | |
def writeUsingFile(): | |
with open(fileName, 'w', encoding='iso8859') as writer: | |
for i in range(1, numOfNums): | |
writer.write(chr(i & 0xff)) | |
def readUsingFile(): | |
with open(fileName, 'r', encoding='iso8859') as reader: | |
for i in range(1, numOfNums): | |
reader.read(1) | |
os.remove(fileName) | |
def foo(x): | |
time1 = time.perf_counter() | |
writeUsingFile() | |
time2 = time.perf_counter() | |
readUsingFile() | |
time3 = time.perf_counter() | |
tmp1 = numOfNums / 1024 / 1024 | |
readTime = tmp1 / (time3 - time2) | |
writeTime = tmp1 / (time2 - time1) | |
print("{0} {1}".format(readTime, writeTime)) | |
sys.stdout.flush() | |
return [readTime, writeTime] | |
if os.path.exists(fileName): | |
os.remove(fileName) | |
tmp1 = [foo(x) for x in range(1, reps + 1)] | |
read, write = map(sum, zip(*(tmp1[1:]))) | |
tmp2 = reps - 1 | |
print("Bytes: {0} MB, ReadRate: {1} MB/s, WriteRate: {2}".format(numOfNums / 1024 / 1024, read / tmp2, write / tmp2)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if ARGV.size < 1 | |
print("Provide filename\n") | |
exit(-1) | |
end | |
k = 256 | |
$numOfNums = k * 1024 * 1024 | |
$fileName = ARGV[0] | |
$reps = 6 | |
def writeUsingFile() | |
open($fileName, 'wb') do |writer| | |
(1..$numOfNums).each { |i| writer.putc(i & 0xff) } | |
end | |
end | |
def readUsingFile() | |
open($fileName, 'rb') do |reader| | |
(1..$numOfNums).each { reader.getc() } | |
end | |
File.delete($fileName) | |
end | |
if File.exists?($fileName) | |
File.delete($fileName) | |
end | |
(read, write) = (1..$reps).collect { | |
time1 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond) | |
writeUsingFile() | |
time2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond) | |
readUsingFile() | |
time3 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond) | |
tmp1 = $numOfNums.to_f / 1024 / 1024 * 1e9 | |
readTime = tmp1 / (time3 - time2) | |
writeTime = tmp1 / (time2 - time1) | |
print("#{readTime}, #{writeTime}\n") | |
STDOUT.flush | |
[readTime, writeTime] | |
}[1..$reps].inject([0, 0]) { |x, y| [x[0] + y[0], x[1] + y[1]] } | |
tmp1 = $reps - 1 | |
print "Bytes: #{$numOfNums / 1024 / 1024} MB, ReadRate: #{read / tmp1} MB/s, WriteRate: #{write / tmp1} MB/s" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.{BufferedInputStream, BufferedOutputStream, FileInputStream, FileOutputStream} | |
import java.nio.file.{Files, Paths} | |
if (args.length < 1) { | |
println("Provide filename") | |
System.exit(-1) | |
} | |
val k = 256 | |
val numOfNums = k * 1024 * 1024 | |
val fileName = args(0) | |
val reps = 6 | |
def writeUsingFile(): Unit = { | |
val writer = new BufferedOutputStream(new FileOutputStream(fileName)) | |
try { | |
1 to numOfNums foreach { x => writer.write(x & 0xff) } | |
} finally | |
writer.close | |
} | |
def readUsingFile(): Unit = { | |
var t = 0 | |
val reader = new BufferedInputStream(new FileInputStream(fileName)) | |
try { | |
1 to numOfNums foreach { _ => reader.read ; t += 1 } | |
} finally | |
reader.close | |
assert(t >= numOfNums) | |
Files.delete(Paths.get(fileName)) | |
} | |
Files.deleteIfExists(Paths.get(fileName)) | |
val (read, write) = 1 to reps map { _ => | |
val time1 = System.nanoTime() | |
writeUsingFile() | |
val time2 = System.nanoTime() | |
readUsingFile() | |
val time3 = System.nanoTime() | |
val tmp1 = numOfNums / 1024 / 1024 * 1e9 | |
val readTime = tmp1 / (time3 - time2) | |
val writeTime = tmp1 / (time2 - time1) | |
println(s"$readTime $writeTime") | |
(readTime, writeTime) | |
} drop 1 reduce { (x, y) => ((x._1 + y._1), (x._2 + y._2)) } | |
val tmp1 = reps -1 | |
println(s"Bytes: ${numOfNums / 1024 / 1024} MB, ReadRate: ${read / tmp1} MB/s, WriteRate: ${write / tmp1} MB/s") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment