package require critcl 0.33
critcl::ccode {
#include <stdio.h>
}
critcl::cproc loadf {char* fn} Tcl_Obj* {
FILE *fd;
Tcl_Obj *r,*s;
char line[1024];
r=Tcl_NewListObj(0,0);
Tcl_IncrRefCount(r);
s=Tcl_NewStringObj("",0);
fd=fopen(fn,"r");
if (!fd) {
return r;
}
while(!feof(fd)) {
int l;
if (!fgets(line,1024,fd)) {
break;
}
l=strlen(line);
if (line[l-1]=='\n') {
line[--l]='\0';
Tcl_AppendToObj(s,line,l);
Tcl_ListObjAppendElement(NULL,r,s);
s=Tcl_NewStringObj("",0);
} else {
Tcl_AppendToObj(s,line,l);
}
}
fclose(fd);
if (Tcl_GetCharLength(s) > 0) {
Tcl_ListObjAppendElement(NULL,r,s);
}
return r;
}
# tcl version for comparison
proc loadf_tcl {file} {
set f [open $file]
fconfigure $f -translation binary
set d [read -nonewline $f]
close $f
split $d \n
}
# use
set lines [loadf something]The critcl version is as much as 3 times faster than the tcl version on a large file.I just noticed that on files with lots of short lines (e.g., /usr/share/dict/words) the critcl version is actually slower than the tcl version. This bears looking into.AMG: Maybe your fgets() is buggy. I suggest using strace to see if it's making unreasonable numbers of read syscalls.
With the conventional wisdom that [read [open $file] [file size $file]] is faster than [read [open $file]], I wonder if the critcl function is still 3x faster.Wow. I've never ever used critcl before. Now I'm convinced. I didn't even know I had critcl on my system, but the above cut'n'pasted and Just Worked. Nifty. And yes, the critcl version is still faster (after the initial compile)AMG: Conventional wisdom? Why would it be faster to tell read how many bytes to get?

