I/O speed

Stephen Weeks MLton@sourcelight.com
Thu, 21 Sep 2000 16:28:49 -0700 (PDT)


OK.  I am suitably embarrassed.  I fixed TextIO.

Executive Summary:

Here are the numbers for gcc and MLton on my machine for code that reads 1G from 
/dev/zero. 

	time(s)	M/s
MLton	32.39	30
gcc	26.73	37

Details:

I fixed the basis library implementation of TextIO.input1 so that the common
case (i.e. the character is in the I/O buffer) is fast.  Here's the comparison
of gcc and MLton.

Here is the C code.

/* foo.c */
#include <stdio.h>

int main() {
	int ch, size;

     for (;;) {
             ch = getchar();
             if (ch == EOF)
                     break;
             ++size;
     }
}
/* end foo.c */

I compiled foo.c with the following:
  gcc -O2 -o foo -D_IO_getc=_IO_getc_unlocked -D_IO_putc=_IO_putc_unlocked foo.c

I then tested it with the following:
  dd bs=1k count=1000000 </dev/zero | time foo

The system + user was 26.73 seconds.

Spy showed the loop as the following:

0x80483f3:      movl   0x8049550,%edx
0x80483f9:      movl   0x4(%edx),%eax
0x80483fc:      cmpl   0x8(%edx),%eax
0x80483ff:      jb     0x8048410
0x8048410:      movzbl (%eax),%eax
0x8048413:      incl   0x4(%edx)
0x8048416:      cmpl   $0xffffffff,%eax
0x8048419:      jne    0x80483f3


Now, for the MLton version (with the new text-io.sml).

(* z.sml *)
open TextIO
val ins = stdIn
fun loop() =
   case input1 ins of
      NONE => ()
    | SOME _ => loop()
val _ = loop()
(* end z.sml *)

Compiled with "$HOME/mlton/bin/mlton z.sml"

Tested with "dd bs=1k count=1000000 </dev/zero | time z"

The system + user was 32.39 seconds.

Spy showed the loop as the following:

0x804a830:      movl   0x1c(%ebx),%eax
0x804a833:      movl   (%eax),%edx
0x804a835:      movl   0x805096c,%eax
0x804a83a:      movl   (%eax),%edi
0x804a83c:      movl   0x8050970,%eax
0x804a841:      cmpl   (%eax),%edi
0x804a843:      jge    0x804aadc
0x804a849:      movl   0x805096c,%eax
0x804a84e:      leal   0x1(%edi),%ecx
0x804a851:      movl   %ecx,(%eax)
0x804a853:      cmpl   $0xfff,%edi
0x804a859:      jbe    0x804a830