Discussion came up in comp.os.vms/INFO-VAX again about relative speed of various ways to do disk IO on VMS.
I posted some numbers and some code.
This is basically the same, but with more options tested (read: more numbers and more code) and more comments.
Some may find the conclusions interesting.
Other may just be interested in the code examples. Some of the code is trivial, but other are non-trivial.
It is expected that the reader know about VMS, RMS, system services, C and preferrably also the other programming languages used. It is not really beginner friendly.
It may be unusual to start with the conclusion, but here it is:
Speed | Reading records | Reading blocks |
---|---|---|
Very slow | Fortran READ Pascal readln sys$get |
|
Slow | C fgets | |
Medium | Java BufferedReader.readLine | sys$read small blocks sys$qiow small blocks sys$io_performw small blocks |
Fast | C fread small blocks Java InputStream.read small blocks C mmap sys$crmpsc |
|
Very fast | C fread large blocks sys$read large blocks sys$qiow large blocks sys$io_performw large blocks Java InputStream.read large blocks Java FileChannel.map |
And:
There are 3 different ways to do IO:
Record based IO:
Block based IO:
Memory mapped file:
VMS "Fast IO" (sys$io_setup, sys$io_performw/sys$perform, sys$io_cleanup) was added in VMS 7.x for 64 bit platforms as a faster variant of the traditional sys$qiow/sys$qio.
The general assumptions are that:
The test will time counting number of lines in a 100 MB file.
As usual there is an infinite number of possible tests. This is just one test and it it does not in anyway look like a real world application. But it is simple - everybody can understand the code. Sometimes it is better to focus on a very narrow case with code everybody can understand than having a complex realistic case with code where nobody can understand what constructs are fast and what constructs are slow.
The numbers will be different on different systems. But I will assume the main conclusions will still hold.
Actually reading lines (tests run 10 times and rounded average used):
API | VMS 8.4-2L2 Alpha simulator Xeon @ 3.7 GHz SSD |
VMS 8.4-2L3 Itanium 1.6 Ghz HDD |
VMS 9.2-1 VMWare Player Xeon @ 3.7 GHz SSD |
Lines of code |
---|---|---|---|---|
Fortran READ | 550 s | 71 s | 61 s | 34 |
Pascal readln | 280 s | 32 s | 53 s | 44 |
C fgets C fgets with RAH C fgets with ctx=stm |
23 s 22 s 23 s |
3.1 s 3.0 s 3.1 s |
19 s 19 s 19 s |
36 |
sys$get sys$get with RAH |
210 s 210 s |
26 s 26 s |
49 s 48 s |
76 |
Java BufferedReader.readLine | 40 s | 1.40 s | 0.50 s | 27 |
Read ahead does not seem to make a big difference for this particular case. But it may matter more for other cases.
Java BufferedReader.readLine is much faster than anything else (except on slow Alpha simulator with old Java version) - and that is despite it converting 8 bit bytes to 16 bit UTF-16 code units. The Java IO library must do something very efficiently. The class name BufferedReader imply a buffer, but there are no unbuffered readLine and BufferedReader.readLine is the way you read text lines in Java.
Test of sys$get could have been done in another language like Fortran or Pascal, but it seems reasonable to assume C would be the language of choice today.
Reading disk blocks and parsing lines (tests run 10 times and rounded average used):
API | VMS 8.4-2L2 Alpha simulator Xeon @ 3.7 GHz SSD |
VMS 8.4-2L3 Itanium 1.6 Ghz HDD |
VMS 9.2-1 VMWare Player Xeon @ 3.7 GHz SSD |
Lines of code |
---|---|---|---|---|
C fread 512 byte C fread 512 byte with RAH |
3.7 s 3.3 s |
0.35 s 0.30 s |
0.70 s 0.60 s |
45 |
C fread 5120 bytes C fread 5120 bytes with RAH |
3.0 s 2.6 s |
0.30 s 0.25 s |
0.35 s 0.30 s |
|
C fread 51200 bytes C fread 51200 bytes with RAH |
2.9 s 2.5 s |
0.30 s 0.25 s |
0.30 s 0.25 s |
|
C fread 512000 bytes C fread 512000 bytes with RAH |
2.9 s 2.5 s |
0.30 s 0.25 s |
0.30 s 0.25 s |
|
sys$read 512 bytes sys$read 512 bytes with RAH |
16.3 s 16.3 s |
1.50 s 1.50 s |
2.20 s 2.20 s |
84 |
sys$read 5120 bytes sys$read 5120 bytes with RAH |
4.1 s 4.1 s |
0.40 s 0.40 s |
0.45 s 0.45 s |
|
sys$read 51200 bytes sys$read 51200 bytes with RAH |
2.2 s 2.2 s |
0.25 s 0.25 s |
0.20 s 0.20 s |
|
sys$read 512000 bytes sys$read 512000 bytes with RAH |
2.2 s 2.2 s |
0.25 s 0.25 s |
0.20 s 0.20 s |
|
sys$qiow 512 bytes sys$qio (max. 60 outstanding) 512 bytes sys$io_performw 512 bytes |
12.8 s 12.0 s 12.1 s |
1.05 s 1.05 s 1.10 s |
1.30 s 1.20 s 1.10 s |
161 201 202 |
sys$qiow 5120 bytes sys$qio (max. 60 outstanding) 5120 bytes sys$io_performw 5120 bytes |
3.8 s 3.6 s 3.4 s |
0.35 s 0.30 s 0.35 s |
0.35 s 0.30 s 0.30 s |
|
sys$qiow 51200 bytes sys$qio (max. 60 outstanding) 51200 bytes sys$io_performw 51200 bytes |
2.3 s 2.1 s 1.9 s |
0.25 s 0.25 s 0.25 s |
0.25 s 0.20 s 0.20 s |
|
sys$qiow 512000 bytes sys$qio (max. 60 outstanding) 512000 bytes sys$io_performw 512000 bytes |
1.9 s 1.9 s 2.0 s |
0.30 s 0.70 s 0.30 s |
0.35 s 0.25 s 0.30 s |
|
Java InputStream.read 512 bytes | 9.9 s | 0.50 s | 0.40 s | 32 |
Java InputStream.read 5120 bytes | 7.1 s | 0.30 s | 0.20 s | |
Java InputStream.read 51200 bytes | 6.8 s | 0.30 s | 0.20 s | |
Java InputStream.read 512000 bytes | 6.7 s | 0.30 s | 0.20 s | |
C mmap | 3.1 s | 0.50 s | 0.80 s | 57 |
sys$crmpsc | 2.7 s | 0.40 s | 0.70 s | 77 |
Java FileChannel.map | 48 s | 0.55 s | 0.15 s | 34 |
Read ahead does not seem to make a big difference for this particular case. But it may matter more for other cases.
At least for this example then sys$io_performw is not significant faster than sys$qiow. Maybe it is for other use cases, but somehow I doubt that the saved CPU cycles will matter much on modern fast CPU's.
At least for this example then sys$qio (not W) is not significant faster than sys$qiow. Maybe it is for other use cases where the program actually do something while waiting for IO to complete.
It was expected that reading blocks was faster than reading records, but it is somewhat surprising that the difference is so huge (except for Java).
Test of sys$read and the system services (sys$qiow, sys$qio, sys$io_performw and sys$crmpsc) could have been done in another language like Fortran or Pascal, but it seems reasonable to assume C would be the language of choice today.
For those really interested in the code here it comes.
The code is the ultimate documentation of what was tested. And everybody can check if I have made any mistakes. I hope not but one never knows.
If you want everything to test yourself, then get this kit - it has all source, scripts etc..
The file generating program expect two parameters:
The file reading programs expect two parameters:
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Gen {
public static void main(String[] args) throws IOException {
int size = Integer.parseInt(args[1]);
long t1 = System.currentTimeMillis();
try(PrintWriter pw = new PrintWriter(new FileWriter(args[0]))) {
for(int i = 0; i < size / 10; i++) {
for(int j = 0; j < 10 - System.getProperty("line.separator").length(); j++) {
pw.print(Integer.toString(i % 10));
}
pw.println();
}
}
long t2 = System.currentTimeMillis();
System.out.printf("Gen (%d bytes) : %d ms\n", size, t2 - t1);
}
}
or if Java 5:
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Gen {
public static void main(String[] args) throws IOException {
int size = Integer.parseInt(args[1]);
long t1 = System.currentTimeMillis();
PrintWriter pw = new PrintWriter(new FileWriter(args[0]));
for(int i = 0; i < size / 10; i++) {
for(int j = 0; j < 10 - System.getProperty("line.separator").length(); j++) {
pw.print(Integer.toString(i % 10));
}
pw.println();
}
pw.close();
long t2 = System.currentTimeMillis();
System.out.printf("Gen (%d bytes) : %d ms\n", size, t2 - t1);
}
}
program plainread
integer*4 i
character*256 cmdlin
integer*4 cmdlinlen, ix, expect
call lib$get_foreign(cmdlin,,cmdlinlen)
ix = index(cmdlin(1:cmdlinlen), ' ')
read(cmdlin(ix+1:cmdlinlen), '(I)') expect
do 100 i = 1,10
call test(cmdlin(1:ix-1), expect)
100 continue
end
c
subroutine test(fnm, expect)
character*(*) fnm
integer*4 expect
integer*4 n
integer*8 t1, t2
character*10 line
call sys$gettim(t1)
open(unit=1, file=fnm, status='old')
n = 0
100 read(unit=1, fmt=300, end=200) line
n = n + 1
goto 100
200 if(n.ne.expect) then
write(*,fmt=400) n
end if
close(unit=1)
call sys$gettim(t2)
write(*,fmt=500) (t2 - t1) / 10000
300 format(a)
400 format(1x,i8,' lines')
500 format(1x,'Fortran read : ',i6,' ms')
end
[inherit('sys$library:pascal$lib_routines')]
program PlainReadLn(input, output);
type
string = varying[32767] of char;
procedure test(fnm : string; expect : integer);
var
f : text;
line : string;
t1, t2 : Cardinal;
n : integer;
begin
t1 := Clock;
open(f, fnm, old);
reset(f);
n := 0;
while not eof(f) do begin
readln(f, line);
n := n + 1;
end;
if n <> expect then begin
writeln(n:1,' lines');
end;
close(f);
t2 := Clock;
writeln('Pascal readln : ', (t2 - t1):1, ' ms');
end;
var
ix, expect, i : integer;
cmdlin, fnm : string;
begin
lib$get_foreign(resultant_string:=cmdlin.body,resultant_length:=cmdlin.length);
ix := index(cmdlin, ' ');
fnm := substr(cmdlin, 1, ix - 1);
readv(substr(cmdlin, ix + 1), expect);
for i := 1 to 10 do begin
test(fnm, expect);
end;
end.
#include <stdio.h>
#include <stdlib.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect)
{
FILE *fp;
char line[1000];
TIMECOUNT_T t1, t2;
int n;
t1 = GET_TIMECOUNT;
fp = fopen(fnm, "r");
n = 0;
while(fgets(line, sizeof(line), fp))
{
n++;
}
if(n != expect)
{
printf("%d lines\n", n);
}
fclose(fp);
t2 = GET_TIMECOUNT;
printf("C fgets : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect)
{
FILE *fp;
char line[1000];
TIMECOUNT_T t1, t2;
int n;
t1 = GET_TIMECOUNT;
fp = fopen(fnm, "r", "rop=rah", "mbc=127", "mbf=127");
n = 0;
while(fgets(line, sizeof(line), fp))
{
n++;
}
if(n != expect)
{
printf("%d lines\n", n);
}
fclose(fp);
t2 = GET_TIMECOUNT;
printf("C fgets (rop=rah mbc=127 mbf=127) : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect)
{
FILE *fp;
char line[1000];
TIMECOUNT_T t1, t2;
int n;
t1 = GET_TIMECOUNT;
fp = fopen(fnm, "r", "ctx=stm");
n = 0;
while(fgets(line, sizeof(line), fp))
{
n++;
}
if(n != expect)
{
printf("%d lines\n", n);
}
fclose(fp);
t2 = GET_TIMECOUNT;
printf("C fgets (ctx=stm): %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <starlet.h>
#include <rms.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect)
{
long stat;
struct FAB fab;
struct RAB rab;
char buf[1000];
TIMECOUNT_T t1, t2;
int n;
t1 = GET_TIMECOUNT;
fab = cc$rms_fab;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_GET;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
rab = cc$rms_rab;
rab.rab$l_fab = &fab;
rab.rab$b_rac = RAB$C_SEQ;
stat = sys$connect(&rab, 0 ,0);
if(!(stat & 1))
{
printf("sys$connect stat = %d\n", stat);
}
n = 0;
for(;;)
{
rab.rab$l_ubf = buf;
rab.rab$w_usz = sizeof(buf);
stat = sys$get(&rab, 0, 0);
if(stat == RMS$_EOF) break;
if(!(stat & 1))
{
printf("sys$get stat = %d\n", stat);
}
buf[rab.rab$w_rsz] = 0;
n++;
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$disconnect(&rab, 0, 0);
if(!(stat & 1))
{
printf("sys$disconnect stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
t2 = GET_TIMECOUNT;
printf("sys$get : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <starlet.h>
#include <rms.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect)
{
long stat;
struct FAB fab;
struct RAB rab;
char buf[1000];
TIMECOUNT_T t1, t2;
int n;
t1 = GET_TIMECOUNT;
fab = cc$rms_fab;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_GET;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
rab = cc$rms_rab;
rab.rab$l_fab = &fab;
rab.rab$b_rac = RAB$C_SEQ;
rab.rab$l_rop = RAB$M_RAH;
rab.rab$b_mbc = 127;
rab.rab$b_mbf = 127;
stat = sys$connect(&rab, 0 ,0);
if(!(stat & 1))
{
printf("sys$connect stat = %d\n", stat);
}
n = 0;
for(;;)
{
rab.rab$l_ubf = buf;
rab.rab$w_usz = sizeof(buf);
stat = sys$get(&rab, 0, 0);
if(stat == RMS$_EOF) break;
if(!(stat & 1))
{
printf("sys$get stat = %d\n", stat);
}
buf[rab.rab$w_rsz] = 0;
n++;
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$disconnect(&rab, 0, 0);
if(!(stat & 1))
{
printf("sys$disconnect stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
t2 = GET_TIMECOUNT;
printf("sys$get (rop=rah mbc=127 mbf=127) : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadLine {
private static void test(String fnm, int expect) throws IOException {
long t1 = System.currentTimeMillis();
try(BufferedReader br = new BufferedReader(new FileReader(fnm))) {
int n = 0;
@SuppressWarnings("unused")
String line;
while((line = br.readLine()) != null) {
n++;
}
if(n != expect) {
System.out.printf("%d lines\n", n);
}
}
long t2 = System.currentTimeMillis();
System.out.printf("Java BufferedReader.readLine : %d ms\n", t2 - t1);
}
public static void main(String[] args) throws IOException {
for(int i = 0; i < 10; i++) {
test(args[0], Integer.parseInt(args[1]));
}
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadLine {
private static void test(String fnm, int expect) throws IOException {
long t1 = System.currentTimeMillis();
BufferedReader br = new BufferedReader(new FileReader(fnm));
int n = 0;
@SuppressWarnings("unused")
String line;
while((line = br.readLine()) != null) {
n++;
}
if(n != expect) {
System.out.printf("%d lines\n", n);
}
br.close();
long t2 = System.currentTimeMillis();
System.out.printf("Java BufferedReader.readLine : %d ms\n", t2 - t1);
}
public static void main(String[] args) throws IOException {
for(int i = 0; i < 10; i++) {
test(args[0], Integer.parseInt(args[1]));
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect, int blksiz)
{
FILE *fp;
char *buf;
TIMECOUNT_T t1, t2;
int n, bufsiz, i;
t1 = GET_TIMECOUNT;
buf = malloc(blksiz);
fp = fopen(fnm, "r");
n = 0;
while((bufsiz = fread(buf, 1, blksiz, fp)) > 0)
{
for(i = 0; i < bufsiz; i++)
{
if(buf[i] == '\n') n++;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
free(buf);
fclose(fp);
t2 = GET_TIMECOUNT;
printf("C fread (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect, int blksiz)
{
FILE *fp;
char *buf;
TIMECOUNT_T t1, t2;
int n, bufsiz, i;
t1 = GET_TIMECOUNT;
buf = malloc(blksiz);
fp = fopen(fnm, "r", "rop=rah", "mbc=127", "mbf=127");
n = 0;
while((bufsiz = fread(buf, 1, blksiz, fp)) > 0)
{
for(i = 0; i < bufsiz; i++)
{
if(buf[i] == '\n') n++;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
free(buf);
fclose(fp);
t2 = GET_TIMECOUNT;
printf("C fread (rop=rah mbc=127 mbf=127) (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <starlet.h>
#include <rms.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect, int blksiz)
{
long stat;
struct FAB fab;
struct RAB rab;
char *buf;
TIMECOUNT_T t1, t2;
int n, i;
t1 = GET_TIMECOUNT;
buf = malloc(blksiz);
fab = cc$rms_fab;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_BIO | FAB$M_GET;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
rab = cc$rms_rab;
rab.rab$l_fab = &fab;
rab.rab$b_rac = RAB$C_SEQ;
stat = sys$connect(&rab, 0 ,0);
if(!(stat & 1))
{
printf("sys$connect stat = %d\n", stat);
}
n = 0;
for(;;)
{
rab.rab$l_ubf = buf;
rab.rab$w_usz = blksiz;
stat = sys$read(&rab, 0, 0);
if(stat == RMS$_EOF) break;
if(!(stat & 1))
{
printf("sys$read stat = %d\n", stat);
}
for(i = 0; i < rab.rab$w_rsz; i++)
{
if(buf[i] == '\n') n++;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$disconnect(&rab, 0, 0);
if(!(stat & 1))
{
printf("sys$disconnect stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
free(buf);
t2 = GET_TIMECOUNT;
printf("sys$read (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <starlet.h>
#include <rms.h>
#include "high_res_timer.h"
static void test(const char *fnm, int expect, int blksiz)
{
long stat;
struct FAB fab;
struct RAB rab;
char *buf;
TIMECOUNT_T t1, t2;
int n, i;
t1 = GET_TIMECOUNT;
buf = malloc(blksiz);
fab = cc$rms_fab;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_BIO | FAB$M_GET;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
rab = cc$rms_rab;
rab.rab$l_fab = &fab;
rab.rab$b_rac = RAB$C_SEQ;
rab.rab$l_rop = RAB$M_RAH;
rab.rab$b_mbc = 127;
rab.rab$b_mbf = 127;
stat = sys$connect(&rab, 0 ,0);
if(!(stat & 1))
{
printf("sys$connect stat = %d\n", stat);
}
n = 0;
for(;;)
{
rab.rab$l_ubf = buf;
rab.rab$w_usz = blksiz;
stat = sys$read(&rab, 0, 0);
if(stat == RMS$_EOF) break;
if(!(stat & 1))
{
printf("sys$read stat = %d\n", stat);
}
for(i = 0; i < rab.rab$w_rsz; i++)
{
if(buf[i] == '\n') n++;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$disconnect(&rab, 0, 0);
if(!(stat & 1))
{
printf("sys$disconnect stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
free(buf);
t2 = GET_TIMECOUNT;
printf("sys$read (rop=rah mbc=127 mbf=127) (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <descrip.h>
#include <starlet.h>
#include <rms.h>
#include <ssdef.h>
#include <iodef.h>
#include <fibdef.h>
#include <atrdef.h>
#include "high_res_timer.h"
struct FAT
{
unsigned long fat$v_rtype: 4;
unsigned long fat$v_fileorg: 4;
unsigned char fat$b_rattrib;
unsigned short fat$w_rsize;
unsigned short fat$w_hiblkh,fat$w_hiblkl;
unsigned short fat$w_efblkh,fat$w_efblkl;
unsigned short fat$w_ffbyte;
unsigned char fat$b_bktsize;
unsigned char fat$b_vfcsize;
unsigned short fat$w_maxrec;
unsigned short fat$w_defext;
unsigned short fat$w_gbc;
unsigned char fill_1[8];
unsigned short fat$w_versions;
};
static long long offset(int blkno, int bytno)
{
return (blkno - 1) * 512L + bytno;
}
static void test(const char *fnm, int expect, int blksiz)
{
long stat;
unsigned short iosb[4];
struct FAB fab;
struct NAM nam;
struct dsc$descriptor_s devdesc;
short chan;
struct fibdef fib;
long fibdesc[] = { FIB$K_LENGTH, (long)&fib };
struct FAT fat;
struct atrdef atr[] = { {ATR$S_RECATTR, ATR$C_RECATTR, &fat},{ 0, 0, NULL } };
long eof;
short ffb;
int adjblksiz;
char *buf;
char expfnm[NAM$C_MAXRSS];
int ix, len, n, i;
TIMECOUNT_T t1, t2;
t1 = GET_TIMECOUNT;
buf = malloc(blksiz);
fab = cc$rms_fab;
nam = cc$rms_nam;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_GET;
fab.fab$l_nam = &nam;
nam.nam$b_rss = sizeof(expfnm) - 1;
nam.nam$l_rsa = expfnm;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
devdesc.dsc$b_dtype = DSC$K_DTYPE_T;
devdesc.dsc$b_class = DSC$K_CLASS_S;
devdesc.dsc$w_length = strlen(expfnm);
devdesc.dsc$a_pointer = expfnm;
stat = sys$assign(&devdesc, &chan, 0, 0, 0);
if(!(stat & 1))
{
printf("sys$assign stat = %d\n", stat);
}
memset(&fib, 0, sizeof(fib));
fib.fib$w_fid[0] = nam.nam$w_fid[0];
fib.fib$w_fid[1] = nam.nam$w_fid[1];
fib.fib$w_fid[2] = nam.nam$w_fid[2];
stat = sys$qiow(0, chan, IO$_ACCESS | IO$M_ACCESS, iosb, 0, 0, &fibdesc, 0, 0, 0, &atr, 0);
if(!(stat & 1))
{
printf("sys$qiow io$_access stat = %d\n", stat);
}
eof = (fat.fat$w_efblkh << 16) | fat.fat$w_efblkl;
ffb = fat.fat$w_ffbyte;
ix = 1;
n = 0;
for(;;)
{
if(ix > eof) break;
if(offset(ix, blksiz) <= offset(eof, ffb))
{
adjblksiz = blksiz;
}
else
{
adjblksiz = offset(eof, ffb) - offset(ix, 0);
}
stat = sys$qiow(0, chan, IO$_READVBLK, iosb, 0, 0, buf, adjblksiz, ix, 0, 0, 0);
if(iosb[0] == SS$_ENDOFFILE)
{
break;
}
else if(!(stat & 1))
{
printf("sys$qiow io$_readvblk stat = %d\n", stat);
}
else if(!(iosb[0] & 1))
{
printf("sys$qiow io$_readvblk iosb[0] = %d\n", iosb[0]);
}
len = (iosb[2] << 16) | iosb[1];
for(i = 0; i < len; i++)
{
if(buf[i] == '\n') n++;
}
ix = ix + blksiz / 512;
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$qiow(0, chan, IO$_DEACCESS, iosb, 0, 0, &fibdesc, 0, 0, 0, &atr, 0);
if(!(stat & 1))
{
printf("sys$qiow io$_deaccess stat = %d\n", stat);
}
stat = sys$dassgn(chan);
if(!(stat & 1))
{
printf("sys$dassgn stat = %d\n", stat);
}
free(buf);
t2 = GET_TIMECOUNT;
printf("sys$qiow (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <descrip.h>
#include <starlet.h>
#include <rms.h>
#include <ssdef.h>
#include <iodef.h>
#include <fibdef.h>
#include <atrdef.h>
#include "high_res_timer.h"
struct FAT
{
unsigned long fat$v_rtype: 4;
unsigned long fat$v_fileorg: 4;
unsigned char fat$b_rattrib;
unsigned short fat$w_rsize;
unsigned short fat$w_hiblkh,fat$w_hiblkl;
unsigned short fat$w_efblkh,fat$w_efblkl;
unsigned short fat$w_ffbyte;
unsigned char fat$b_bktsize;
unsigned char fat$b_vfcsize;
unsigned short fat$w_maxrec;
unsigned short fat$w_defext;
unsigned short fat$w_gbc;
unsigned char fill_1[8];
unsigned short fat$w_versions;
};
static long long offset(int blkno, int bytno)
{
return (blkno - 1) * 512L + bytno;
}
#define PAR_FACTOR 60
static void test(const char *fnm, int expect, int blksiz)
{
long stat;
unsigned short iosb[PAR_FACTOR][4];
struct FAB fab;
struct NAM nam;
struct dsc$descriptor_s devdesc;
short chan;
struct fibdef fib;
long fibdesc[] = { FIB$K_LENGTH, (long)&fib };
struct FAT fat;
struct atrdef atr[] = { {ATR$S_RECATTR, ATR$C_RECATTR, &fat},{ 0, 0, NULL } };
long eof;
short ffb;
int adjblksiz;
char *buf;
char expfnm[NAM$C_MAXRSS];
int ix, len, n, i;
int nread, slot, efn;
int outstand[PAR_FACTOR] = { 0 };
TIMECOUNT_T t1, t2;
t1 = GET_TIMECOUNT;
buf = malloc(PAR_FACTOR * blksiz);
fab = cc$rms_fab;
nam = cc$rms_nam;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_GET;
fab.fab$l_nam = &nam;
nam.nam$b_rss = sizeof(expfnm) - 1;
nam.nam$l_rsa = expfnm;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
devdesc.dsc$b_dtype = DSC$K_DTYPE_T;
devdesc.dsc$b_class = DSC$K_CLASS_S;
devdesc.dsc$w_length = strlen(expfnm);
devdesc.dsc$a_pointer = expfnm;
stat = sys$assign(&devdesc, &chan, 0, 0, 0);
if(!(stat & 1))
{
printf("sys$assign stat = %d\n", stat);
}
memset(&fib, 0, sizeof(fib));
fib.fib$w_fid[0] = nam.nam$w_fid[0];
fib.fib$w_fid[1] = nam.nam$w_fid[1];
fib.fib$w_fid[2] = nam.nam$w_fid[2];
stat = sys$qiow(0, chan, IO$_ACCESS | IO$M_ACCESS, iosb, 0, 0, &fibdesc, 0, 0, 0, &atr, 0);
if(!(stat & 1))
{
printf("sys$qiow io$_access stat = %d\n", stat);
}
eof = (fat.fat$w_efblkh << 16) | fat.fat$w_efblkl;
ffb = fat.fat$w_ffbyte;
ix = 1;
n = 0;
nread = 0;
for(;;)
{
if(ix > eof) break;
if(offset(ix, blksiz) <= offset(eof, ffb))
{
adjblksiz = blksiz;
}
else
{
adjblksiz = offset(eof, ffb) - offset(ix, 0);
}
slot = nread % PAR_FACTOR;
efn = slot + 1;
if(outstand[slot])
{
stat = sys$synch(efn, iosb[slot]);
if(!(stat & 1))
{
printf("sys$synch stat = %d\n", stat);
}
if(iosb[slot][0] == SS$_ENDOFFILE)
{
break;
}
else if(!(iosb[slot][0] & 1))
{
printf("sys$qio io$_readvblk iosb[0] = %d\n", iosb[slot][0]);
}
len = (iosb[slot][2] << 16) | iosb[slot][1];
for(i = 0; i < len; i++)
{
if(buf[slot * blksiz + i] == '\n') n++;
}
outstand[slot] = 0;
}
stat = sys$qio(efn, chan, IO$_READVBLK, iosb[slot], 0, 0, buf + slot * blksiz, adjblksiz, ix, 0, 0, 0);
if(!(stat & 1))
{
printf("sys$qio io$_readvblk stat = %d\n", stat);
}
outstand[slot] = 1;
ix = ix + blksiz / 512;
nread++;
}
for(slot = 0; slot < PAR_FACTOR; slot++)
{
if(outstand[slot])
{
efn = slot + 1;
stat = sys$synch(efn, iosb[slot]);
if(iosb[slot][0] == SS$_ENDOFFILE)
{
continue;
}
else if(!(iosb[slot][0] & 1))
{
printf("sys$qio io$_readvblk iosb[0] = %d\n", iosb[slot][0]);
}
len = (iosb[slot][2] << 16) | iosb[slot][1];
for(i = 0; i < len; i++)
{
if(buf[slot * blksiz + i] == '\n') n++;
}
outstand[slot] = 0;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$qiow(0, chan, IO$_DEACCESS, iosb, 0, 0, &fibdesc, 0, 0, 0, &atr, 0);
if(!(stat & 1))
{
printf("sys$qiow io$_deaccess stat = %d\n", stat);
}
stat = sys$dassgn(chan);
if(!(stat & 1))
{
printf("sys$dassgn stat = %d\n", stat);
}
free(buf);
t2 = GET_TIMECOUNT;
printf("sys$qio (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <descrip.h>
#include <starlet.h>
#include <rms.h>
#include <ssdef.h>
#include <iodef.h>
#include <iosadef.h>
#include <fibdef.h>
#include <atrdef.h>
#include <gen64def.h>
#pragma pointer_size save
#pragma pointer_size 64
typedef void *void_ptr64;
#pragma pointer_size restore
#include "high_res_timer.h"
struct FAT
{
unsigned long fat$v_rtype: 4;
unsigned long fat$v_fileorg: 4;
unsigned char fat$b_rattrib;
unsigned short fat$w_rsize;
unsigned short fat$w_hiblkh,fat$w_hiblkl;
unsigned short fat$w_efblkh,fat$w_efblkl;
unsigned short fat$w_ffbyte;
unsigned char fat$b_bktsize;
unsigned char fat$b_vfcsize;
unsigned short fat$w_maxrec;
unsigned short fat$w_defext;
unsigned short fat$w_gbc;
unsigned char fill_1[8];
unsigned short fat$w_versions;
};
static long long offset(int blkno, int bytno)
{
return (blkno - 1) * 512L + bytno;
}
static __align(13) char realbuf[819200];
static __align(13) union { iosa fastiosb; char dummy[8192]; } fast;
static void test(const char *fnm, int expect, int blksiz)
{
long stat;
unsigned short iosb[4];
struct FAB fab;
struct NAM nam;
struct dsc$descriptor_s devdesc;
short chan;
struct fibdef fib;
long fibdesc[] = { FIB$K_LENGTH, (long)&fib };
struct FAT fat;
struct atrdef atr[] = { {ATR$S_RECATTR, ATR$C_RECATTR, &fat},{ 0, 0, NULL } };
struct _generic_64 realbufh, fasth;
void_ptr64 realbufptr, *fastptr;
long long realbuflen, fastlen;
long long fh;
long eof;
short ffb;
int adjblksiz;
char expfnm[NAM$C_MAXRSS];
int ix, len, n, i;
TIMECOUNT_T t1, t2;
t1 = GET_TIMECOUNT;
fab = cc$rms_fab;
nam = cc$rms_nam;
fab.fab$l_fna = (char *)fnm;
fab.fab$b_fns = strlen(fnm);
fab.fab$b_fac = FAB$M_GET;
fab.fab$l_nam = &nam;
nam.nam$b_rss = sizeof(expfnm) - 1;
nam.nam$l_rsa = expfnm;
stat = sys$open(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$open stat = %d\n", stat);
}
stat = sys$close(&fab, 0, 0);
if(!(stat & 1))
{
printf("sys$close stat = %d\n", stat);
}
devdesc.dsc$b_dtype = DSC$K_DTYPE_T;
devdesc.dsc$b_class = DSC$K_CLASS_S;
devdesc.dsc$w_length = strlen(expfnm);
devdesc.dsc$a_pointer = expfnm;
stat = sys$assign(&devdesc, &chan, 0, 0, 0);
if(!(stat & 1))
{
printf("sys$assign stat = %d\n", stat);
}
memset(&fib, 0, sizeof(fib));
fib.fib$w_fid[0] = nam.nam$w_fid[0];
fib.fib$w_fid[1] = nam.nam$w_fid[1];
fib.fib$w_fid[2] = nam.nam$w_fid[2];
stat = sys$qiow(0, chan, IO$_ACCESS | IO$M_ACCESS, iosb, 0, 0, &fibdesc, 0, 0, 0, &atr, 0);
if(!(stat & 1))
{
printf("sys$qiow io$_access stat = %d\n", stat);
}
eof = (fat.fat$w_efblkh << 16) | fat.fat$w_efblkl;
ffb = fat.fat$w_ffbyte;
stat = sys$create_bufobj_64(realbuf, sizeof(realbuf), 0, 0, &realbufptr, &realbuflen, &realbufh);
if(!(stat & 1))
{
printf("sys$create_bufobj_64 realbuf stat = %d\n", stat);
}
stat = sys$create_bufobj_64(&fast, sizeof(fast), 0, 0, &fastptr, &fastlen, &fasth);
if(!(stat & 1))
{
printf("sys$create_bufobj_64 fast stat = %d\n", stat);
}
stat = sys$io_setup (IO$_READVBLK, &realbufh, &fasth, 0, 0, &fh);
if(!(stat & 1))
{
printf("sys$io_setup stat = %d\n", stat);
}
ix = 1;
n = 0;
for(;;)
{
if(ix > eof) break;
if(offset(ix, blksiz) <= offset(eof, ffb))
{
adjblksiz = blksiz;
}
else
{
adjblksiz = offset(eof, ffb) - offset(ix, 0);
}
stat = sys$io_performw(fh, chan, &fast.fastiosb, realbuf, adjblksiz, ix);
if(fast.fastiosb.iosa$l_status == SS$_ENDOFFILE)
{
break;
}
else if(!(stat & 1))
{
printf("sys$io_performw stat = %d\n", stat);
}
else if(!(fast.fastiosb.iosa$l_status & 1))
{
printf("sys$io_performw iosb_status = %d\n", fast.fastiosb.iosa$l_status);
}
len = fast.fastiosb.iosa$ih_count;
for(i = 0; i < len; i++)
{
if(realbuf[i] == '\n') n++;
}
ix = ix + blksiz / 512;
}
if(n != expect)
{
printf("%d lines\n", n);
}
stat = sys$io_cleanup(fh);
if(!(stat & 1))
{
printf("sys$io_cleanup stat = %d\n", stat);
}
stat = sys$delete_bufobj(&realbufh);
if(!(stat & 1))
{
printf("sys$delete_bufobj realbuf stat = %d\n", stat);
}
stat = sys$delete_bufobj(&fasth);
if(!(stat & 1))
{
printf("sys$delete_bufobj fast stat = %d\n", stat);
}
stat = sys$qiow(0, chan, IO$_DEACCESS, iosb, 0, 0, &fibdesc, 0, 0, 0, &atr, 0);
if(!(stat & 1))
{
printf("sys$qiow io$_deaccess stat = %d\n", stat);
}
stat = sys$dassgn(chan);
if(!(stat & 1))
{
printf("sys$dassgn stat = %d\n", stat);
}
t2 = GET_TIMECOUNT;
printf("sys$io_performw (block size %d) : %d ms\n", blksiz, (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int blksiz[] = { 512, 5120, 51200, 512000 };
int i, j;
for(j = 0; j < 4; j++)
{
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]), blksiz[j]);
}
}
return 0;
}
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
public class Read {
private static void test(String fnm, int expect, int blksiz) throws IOException {
long t1 = System.currentTimeMillis();
try(InputStream is = new FileInputStream(fnm)) {
int n = 0;
byte[] buf = new byte[blksiz];
int nb;
while((nb = is.read(buf)) > 0) {
for(int i = 0; i < nb; i++) {
if(buf[i] == '\n') n++;
}
}
if(n != expect) {
System.out.printf("%d lines\n", n);
}
}
long t2 = System.currentTimeMillis();
System.out.printf("Java InputStream.read (block size %d) : %d ms\n", blksiz, t2 - t1);
}
public static void main(String[] args) throws IOException {
int[] blksiz = { 512, 5120, 51200, 512000 };
for(int j = 0; j < 4; j++) {
for(int i = 0; i < 10; i++) {
test(args[0], Integer.parseInt(args[1]), blksiz[j]);
}
}
}
}
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
public class Read {
private static void test(String fnm, int expect, int blksiz) throws IOException {
long t1 = System.currentTimeMillis();
InputStream is = new FileInputStream(fnm);
int n = 0;
byte[] buf = new byte[blksiz];
int nb;
while((nb = is.read(buf)) > 0) {
for(int i = 0; i < nb; i++) {
if(buf[i] == '\n') n++;
}
}
if(n != expect) {
System.out.printf("%d lines\n", n);
}
is.close();
long t2 = System.currentTimeMillis();
System.out.printf("Java InputStream.read (block size %d) : %d ms\n", blksiz, t2 - t1);
}
public static void main(String[] args) throws IOException {
int[] blksiz = { 512, 5120, 51200, 512000 };
for(int j = 0; j < 4; j++) {
for(int i = 0; i < 10; i++) {
test(args[0], Integer.parseInt(args[1]), blksiz[j]);
}
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "high_res_timer.h"
#define OFFSET 0
#define SIZE 102400000
static void test(const char *fnm, int expect)
{
int fd;
char *b;
TIMECOUNT_T t1, t2;
int n, ix;
t1 = GET_TIMECOUNT;
fd = open(fnm, O_RDONLY);
if(fd == -1)
{
printf("Error opening file\n");
exit(1);
}
b = mmap(NULL, SIZE, PROT_READ, MAP_PRIVATE, fd, OFFSET);
if(b == MAP_FAILED)
{
printf("Error mapping file\n");
exit(1);
}
n = 0;
for(ix = 0; ix < SIZE; ix++)
{
if(b[ix] == '\n')
{
n++;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
munmap(b, SIZE);
close(fd);
t2 = GET_TIMECOUNT;
printf("C mmap : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fabdef.h>
#include <secdef.h>
#include <starlet.h>
#define PAGE_SIZE 8192
#define PAGELET_SIZE 512
#define DISKBLOCK_SIZE 512
#define BY2U(n, unit_size) (n - 1) / unit_size + 1
#include "high_res_timer.h"
#define OFFSET 0
#define SIZE 102400000
static void test(char *fnm, int expect)
{
struct FAB myfab;
void *range[2];
unsigned short chan;
long int stat;
char *b;
TIMECOUNT_T t1, t2;
int n, ix;
t1 = GET_TIMECOUNT;
myfab = cc$rms_fab;
myfab.fab$l_fna = fnm;
myfab.fab$b_fns = strlen(fnm);
myfab.fab$l_fop = FAB$M_UFO;
myfab.fab$b_fac = FAB$M_GET;
stat = sys$open(&myfab, 0, 0);
if((stat & 1) == 0)
{
printf("Error opening file\n");
exit(1);
}
range[0] = 0;
range[1] = 0;
chan = myfab.fab$l_stv;
stat = sys$crmpsc(range, range, 0, SEC$M_EXPREG, 0, 0, 0, chan, BY2U(SIZE, PAGELET_SIZE), BY2U(OFFSET, DISKBLOCK_SIZE), 0, 0);
if((stat & 1) == 0)
{
printf("Error mapping file\n");
exit(1);
}
b = range[0];
n = 0;
for(ix = 0; ix < SIZE; ix++)
{
if(b[ix] == '\n')
{
n++;
}
}
if(n != expect)
{
printf("%d lines\n", n);
}
sys$deltva(range, 0, 0);
sys$close(&myfab, 0, 0);
t2 = GET_TIMECOUNT;
printf("sys$crmpsc : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < 10; i++)
{
test(argv[1], atoi(argv[2]));
}
return 0;
}
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Paths;
public class MapFile {
private static final int OFFSET = 0;
private static final int SIZE = 102400000;
private static void test(String fnm, int expect) throws IOException {
long t1 = System.currentTimeMillis();
try(FileChannel fc = FileChannel.open(Paths.get(fnm))) {
ByteBuffer bb = fc.map(MapMode.READ_ONLY, OFFSET, SIZE);
bb.rewind();
int n = 0;
for(int ix = 0; ix < SIZE; ix++) {
byte b = bb.get(ix);
if(b == '\n') {
n++;
}
}
if(n != expect) {
System.out.printf("%d lines\n", n);
}
}
long t2 = System.currentTimeMillis();
System.out.printf("Java FileChannel.map file : %d ms\n", t2 - t1);
}
public static void main(String[] args) throws IOException {
for(int i = 0; i < 10; i++) {
test(args[0], Integer.parseInt(args[1]));
}
}
}
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
public class MapFile {
private static final int OFFSET = 0;
private static final int SIZE = 102400000;
private static void test(String fnm, int expect) throws IOException {
long t1 = System.currentTimeMillis();
FileInputStream fis = new FileInputStream(fnm);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(MapMode.READ_ONLY, OFFSET, SIZE);
bb.rewind();
int n = 0;
for(int ix = 0; ix < SIZE; ix++) {
byte b = bb.get(ix);
if(b == '\n') {
n++;
}
}
if(n != expect) {
System.out.printf("%d lines\n", n);
}
fc.close();
long t2 = System.currentTimeMillis();
System.out.printf("Java FileChannel.map file : %d ms\n", t2 - t1);
}
public static void main(String[] args) throws IOException {
for(int i = 0; i < 10; i++) {
test(args[0], Integer.parseInt(args[1]));
}
}
}
Version | Date | Description |
---|---|---|
1.0 | December 6th 2023 | Initial version |
1.1 | January 14th 2024 | Add SYS$QIO (not W) test |
See list of all articles here
Please send comments to Arne Vajhøj