Richard Suchenwirth 2007-10-23 : In the Tcl chatroom we discussed that Tcl is much slower than Perl in doing simple things like reading a text file line-by-line.
Here is an experiment with tcltcc to expose C's "raw" file I/O directly to Tcl. No encoding or line-end treatment takes place, so files written by these routines are always UTF-8-encoded (of which ASCII is a subset). Also, file handles are just hexdumped into handle strings, no precaution is taken against pilot errors. Caveat usor ... :^)
With maybe some slight modifications, it should be usable with Critcl and Odyce as well.
package require tcc
namespace import tcc::*
cproc fopen {char* name char* mode} char* {
static char handle[16];
FILE* fp = fopen(name, mode);
sprintf(handle,"%p",fp);
return &handle;
}
cproc fgets {char* handle} char* {
FILE* fp;
static char buf[4096];
if(!strcmp(handle,"stdin")) fp = stdin;
else sscanf(handle,"%p",&fp);
fgets(&buf, sizeof(buf)-1, fp);
buf[strlen(buf)-1] = '\0';
return &buf;
}
cproc fputs {char* handle char* str} ok {
FILE* fp;
if(!strcmp(handle,"stdout")) fp = (FILE*)stdout;
else if(!strcmp(handle,"stderr")) fp = (FILE*)stderr;
else sscanf(handle,"%p",&fp);
fputs(str,fp);
fputs("\n",fp);
return TCL_OK;
}
cproc fclose {char* handle} ok {
FILE* fp;
sscanf(handle,"%p",&fp);
fclose(fp);
return TCL_OK;
}
cproc feof {char* handle} int {
FILE* fp;
sscanf(handle,"%p",&fp);
return feof(fp);
}
#-- Testing: writing with quickio
set f [fopen test.txt w]
fputs $f hällo,
fputs $f world!
fclose $f
#-- reading with Tcl, as utf-8
set f [open test.txt]
fconfigure $f -encoding utf-8
puts >>[read $f][close $f]
#-- reading with quickio, should be the same thing
set f [fopen test.txt r]
while 1 {
set line [fgets $f]
if [feof $f] break
puts >>$line<<
}
#-- Test, switchable between Tcl and quickio routines:
set prefix "f"
set f [${prefix}open [lindex $argv 0] r]
while 1 {
set line [${prefix}gets $f]
if {[${prefix}eof $f]} break
${prefix}puts stdout $line
}
${prefix}close $fThe last test gives, on Win XP, Tcl 8.5b1, tcltcc0.2, and a text file with 42741 lines:
Tcl (prefix ""): real 0m3.092s user 0m0.076s sys 0m0.045s quickio (prefix "f"): real 0m3.015s user 0m0.060s sys 0m0.030s