This is Timer.m in view mode; [Download] [Up]
/* * Copyright (c) 1993 Christopher J. Kane. All rights reserved. * * This software is subject to the terms of the MiscKit license * agreement. Refer to the license document included with the * MiscKit distribution for these terms. * * Version: 1.1 (22 October 1993) */ #import "Timer.h" // Beware: this code is a mess // The searchFor:... and replaceAll:... method implementations below // have a few things of note: // 1. A warmup timing is done, just for the sake of silliness // 2. The state of the text that needs to be saved in order to // restore it after timing the Text class is saved, so that // the timing of the Misc_TBMK routines and friends happens // under nearly the same conditions // 3. Searches/replaces are done for the literal string of a // regular expression in the Text object searching when a // regular expression is provided. #define WALLTIME(T1, T2) ((1000000*(T2.tv_sec-T1.tv_sec)+T2.tv_usec-T1.tv_usec)/1000) #define PROCTIME(U1, U2) ((1000000*(U2.ru_utime.tv_sec-U1.ru_utime.tv_sec)+\ U2.ru_utime.tv_usec-U1.ru_utime.tv_usec+1000000*(U2.ru_stime.tv_sec-\ U1.ru_stime.tv_sec)+U2.ru_stime.tv_usec-U1.ru_stime.tv_usec)/1000) @implementation Timer - init { int i; // calibrate a bit struct rusage usage1, usage2; struct timeval t1, t2; gettimeofday(&t1, 0); // just done for "warmup" purposes getrusage(RUSAGE_SELF, &usage1); [self self]; // get crude estimate of method call time getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); wallcallms = 0; proccallms = 0; NXPing(); // why not? for (i=0; i<25; i++) { gettimeofday(&t1, 0); getrusage(RUSAGE_SELF, &usage1); [self self]; getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); wallcallms += WALLTIME(t1, t2); proccallms += PROCTIME(usage1, usage2); } wallcallms /= 25000; proccallms /= 25000; return self; } - (oneway void)makeSelectionVisible { [textObj makeSelectionVisible]; } - (oneway void)replaceSelection:(const char *)replacement { [textObj replaceSelection:replacement]; } - (oneway void)selectTextFrom:(int)start to:(int)end { [textObj selectTextFrom:start to:end]; } - (void)writeSelectionToPasteboard:(in Pasteboard *)pboard asType:(in NXAtom)type { [textObj writeSelectionToPasteboard:pboard asType:type]; } - (int)replaceAll:(const char *)pattern with:(const char *)replacement mode:(SearchMode)mode regexpr:(BOOL)regexpr cases:(BOOL)cases { char buffer[1024]; int r, count=0, end; NXSelPt sp0, spN; struct rusage usage1, usage2; struct timeval t1, t2; NXStream *strm; strm = NXOpenMemory(NULL, 0, NX_READWRITE); [textObj writeText:strm]; // save original text NXSeek(strm, 0, NX_FROMSTART); NXPing(); gettimeofday(&t1, 0); // just done for "warmup" purposes getrusage(RUSAGE_SELF, &usage1); [textObj self]; getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); [textObj getSel:&sp0 :&spN]; [messageField setStringValue:"Timing Text class..."]; [textObj getSel:&sp0 :&spN]; [[textObj window] disableDisplay]; // don't draw (and slow things down) NXPing(); gettimeofday(&t1, 0); // time the Text class getrusage(RUSAGE_SELF, &usage1); if (mode==TextEdgeToTextEdge) { [textObj setSel:0 :0]; // start at the very beginning... while ([textObj findText:pattern ignoreCase:!cases backwards:NO wrap:NO]) { // findText:... does the selecting for us, and // takes care of the end point [textObj replaceSel:replacement]; count++; } } else if (mode== SelStartToSelEnd) { end = spN.cp-strlen(pattern); [textObj setSel:sp0.cp :sp0.cp]; while ([textObj findText:pattern ignoreCase:!cases backwards:NO wrap:NO]) { // here, the we need to keep track of the end position if (sp0.cp>end) break; [textObj replaceSel:replacement]; end += strlen(replacement)-strlen(pattern); count++; } } getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); [[textObj window] reenableDisplay]; [[textObj window] display]; [textWallField setIntValue:WALLTIME(t1, t2)-wallcallms]; [textProcField setIntValue:PROCTIME(usage1, usage2)-proccallms]; [messageField setStringValue:"One moment..."]; NXPing(); [textObj readText:strm]; // restore original text [textObj setSel:sp0.cp :spN.cp]; // restore original selection [messageField setStringValue:"Timing Misc_TBMK routines..."]; NXPing(); gettimeofday(&t1, 0); // time the Misc_TBMK routines getrusage(RUSAGE_SELF, &usage1); r = [textObj replaceAll:pattern with:replacement mode:mode regexpr:regexpr cases:cases]; getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); [tbmkWallField setIntValue:WALLTIME(t1, t2)-wallcallms]; [tbmkProcField setIntValue:PROCTIME(usage1, usage2)-proccallms]; sprintf(buffer, "replaceAll:\"%s\" with:\"%s\" mode:%s regexpr:%s cases:%s", pattern, replacement, (mode==TextEdgeToTextEdge?"TextEdgeToTextEdge": mode==SelStartToSelEnd?"SelStartToSelEnd":"Other"), (regexpr?"YES":"NO"), (cases?"YES":"NO")); [messageField setStringValue:buffer]; NXCloseMemory(strm, NX_FREEBUFFER); return r; } - (int)searchFor:(const char *)pattern mode:(SearchMode)mode reverse:(BOOL)rev regexpr:(BOOL)regexpr cases:(BOOL)cases position:(out int *)pos size:(out int *)size { char buffer[1024]; int r; NXSelPt sp0, spN; struct rusage usage1, usage2; struct timeval t1, t2; [textObj getSel:&sp0 :&spN]; NXPing(); gettimeofday(&t1, 0); // just done for "warmup" purposes getrusage(RUSAGE_SELF, &usage1); [textObj self]; getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); [messageField setStringValue:"Timing Text class..."]; NXPing(); gettimeofday(&t1, 0); // time the Text class getrusage(RUSAGE_SELF, &usage1); [textObj findText:pattern ignoreCase:!cases backwards:rev wrap:YES]; getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); [textWallField setIntValue:WALLTIME(t1, t2)-wallcallms]; [textProcField setIntValue:PROCTIME(usage1, usage2)-proccallms]; [textObj setSel:sp0.cp :spN.cp]; // restore original selection [messageField setStringValue:"Timing Misc_TBMK routines..."]; NXPing(); gettimeofday(&t1, 0); // time the Misc_TBMK routines getrusage(RUSAGE_SELF, &usage1); r = [textObj searchFor:pattern mode:mode reverse:rev regexpr:regexpr cases:cases position:pos size:size]; getrusage(RUSAGE_SELF, &usage2); gettimeofday(&t2, 0); [tbmkWallField setIntValue:WALLTIME(t1, t2)-wallcallms]; [tbmkProcField setIntValue:PROCTIME(usage1, usage2)-proccallms]; sprintf(buffer, "searchFor:\"%s\" mode:%s reverse:%s regexpr:%s cases:%s pos:size:", pattern, (mode==SelEndToSelStart?"SelEndToSelStart": mode==SelStartToSelEnd?"SelStartToSelEnd":"Other"), (rev?"YES":"NO"), (regexpr?"YES":"NO"), (cases?"YES":"NO")); [messageField setStringValue:buffer]; return r; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.