Here's my attempt at this stupid benchmark, more close to the original Lisp version:
#include <stdlib.h>
#include <sys\timeb.h>
#include <wchar.h>
int main ( void )
{
wchar_t *s;
unsigned int i;
struct timeb time_start,time_end;
int total_duration_sec,total_duration_ms,total_duration;
s = L"OP is a faggot";
ftime(&time_start);
for (i=0;i<1000000;i++)
{
wchar_t *junk;
junk = calloc(strlen(s),sizeof(wchar_t));
sprintf(s,"%s",s);
free(junk);
}
ftime(&time_end);
total_duration_sec = time_end.time - time_start.time;
total_duration_ms = time_end.millitm - time_start.millitm;
total_duration = 1000* total_duration_sec + total_duration_ms;
printf( "Total duration %d ms.\n", total_duration);
}
// Gives result:
// Total duration 187 ms.
Lisp version:
CL-USER> (time (loop repeat 1000000 do (format nil "OP is a faggot")))
Evaluation took:
0.687 seconds of real time
0.687500 seconds of total run time (0.687500 user, 0.000000 system)
[ Run times consist of 0.096 seconds GC time, and 0.592 seconds non-GC time. ]
100.15% CPU
1,679,401,305 processor cycles
447,993,992 bytes consed
Lisp version is about 3.6 times as slow, however examining the disassembly of the Lisp version shows that it's actually just a simple loop overall, and the major difference is of course time taken for GC and that format is slower since it has to parse much more complex format strings than sprintf.
To get an idea about FORMAT's capabilities, look at
http://gigamonkeys.com/book/a-few-format-recipes.html
http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm
Disassembly for reference:
; disassembly for (LAMBDA ())
; 240D89D2: BE00093D00 MOV ESI, 4000000 ; no-arg-parsing entry point
; 9D7: EB31 JMP L1
; 9D9: L0: 8BC6 MOV EAX, ESI
; 9DB: 83E804 SUB EAX, 4
; 9DE: 8BF0 MOV ESI, EAX
; 9E0: 8975FC MOV [EBP-4], ESI
; 9E3: 8B3DA8880D24 MOV EDI, [#x240D88A8] ; #<FUNCTION (LAMBDA
; #) {240D88B5}>
; 9E9: 8D5C24F8 LEA EBX, [ESP-8]
; 9ED: 83EC0C SUB ESP, 12
; 9F0: BA0B001022 MOV EDX, 571473931
; 9F5: 8B05AC880D24 MOV EAX, [#x240D88AC] ; #<FDEFINITION object for FORMAT>
; 9FB: B908000000 MOV ECX, 8
; A00: 892B MOV [EBX], EBP
; A02: 8BEB MOV EBP, EBX
; A04: FF5005 CALL DWORD PTR [EAX+5]
; A07: 8B75FC MOV ESI, [EBP-4]
; A0A: L1: 83FE00 CMP ESI, 0
; A0D: 7FCA JNLE L0
; A0F: BA0B001022 MOV EDX, 571473931
; A14: 8BE5 MOV ESP, EBP
; A16: F8 CLC
; A17: 5D POP EBP
; A18: C3 RET