tchrist@convex.com (Tom Christiansen) (05/22/91)
Wondering how badly people who code like C instead of BASIC-PLUS fair in the timing arena, I wrote a mini-benchmark: VERSION 1: for ($i = 0; $i < 100000; $i++) { if ($i) { next; } } VERSION 2: for ($i = 0; $i < 100000; $i++) { next if $i; } Consistently I got this kind of timing behavior. % time perl ptest.1 10.670u 9.105s 0:22.58 87.5% 0+0k 0+1io 36pf+0w % time perl ptest.2 5.690u 0.071s 0:06.54 88.0% 0+0k 1+0io 36pf+0w What the devil is going on here to incur two orders of magnitude more system time, not to mention double the user time??? Some kind of longjmp foo you don't see in the BASIC-PLUS style? Larry, if you're out there, what gives? --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "So much mail, so little time."
ejk@ux2.cso.uiuc.edu (Ed Kubaitis - CSO ) (05/22/91)
You're probably after a detailed explanation, but "Programming Perl" (p 362) advises: o Use modifiers and equivalent && and ||, instead of full-blown conditionals. Statement modifiers avoid the overhead of entering and leaving a block.... The logical operators are translated internally to the equivalent statement modifiers whenever possible. ---------------------------------- Ed Kubaitis (ejk@ux2.cso.uiuc.edu) Computing Services Office - University of Illinois, Urbana
tchrist@convex.COM (Tom Christiansen) (05/22/91)
From the keyboard of ejk@ux2.cso.uiuc.edu (Ed Kubaitis - CSO ): :You're probably after a detailed explanation, but "Programming Perl" (p 362) :advises: Right -- I'm pretty familiar with the book. :-) I'm looking for Larry (or anyone else who's read the code enough) to explain the gory details. --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "So much mail, so little time."
eay@psych.psy.uq.oz.au (Eric Young) (05/23/91)
In article <1991May22.021106.13838@convex.com>, tchrist@convex.com (Tom Christiansen) writes: >VERSION 1: > for ($i = 0; $i < 100000; $i++) { > if ($i) { next; } > } >VERSION 2: > for ($i = 0; $i < 100000; $i++) { > next if $i; > } On a sun4/75 - sunOS 4.1.1 - perl v 4.0.1.1 pl 3 with a trace perlscript I get 10000 'sigcleanup () = 0' system calls when I run VERSION 1 I did not get all these system calls with VERSION 2. I assume the problem is with next out of the { }. trace -c version1 100000 sigcleanup 8 close 7 mmap 5 open ... trace -c version2 8 close 7 mmap 5 open ... eric --- Eric Young | Systems programmer - Psychology Dept. Queensland Uni. ARNnet | eay@psych.psy.uq.oz.au.
lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (05/23/91)
In article <1991May22.021106.13838@convex.com> tchrist@convex.com (Tom Christiansen) writes: : Wondering how badly people who code like C instead of BASIC-PLUS fair : in the timing arena, I wrote a mini-benchmark: : : VERSION 1: : for ($i = 0; $i < 100000; $i++) { : if ($i) { next; } : } : : VERSION 2: : for ($i = 0; $i < 100000; $i++) { : next if $i; : } : : Consistently I got this kind of timing behavior. : : % time perl ptest.1 : 10.670u 9.105s 0:22.58 87.5% 0+0k 0+1io 36pf+0w : : % time perl ptest.2 : 5.690u 0.071s 0:06.54 88.0% 0+0k 1+0io 36pf+0w : : What the devil is going on here to incur two orders : of magnitude more system time, not to mention double : the user time??? Some kind of longjmp foo you don't : see in the BASIC-PLUS style? Larry, if you're out : there, what gives? What gives is probably your setjmp/longjmp doing sigblocks while unwinding the stack. That would explain the system time. You also have the overhead of building and tearing down the block context, including any management of the setjmp/longjmp. One thing that's going on here is that "while" loops are optimized: while (COND) { ... } turns into, more or less, if (COND) { while (1) { last unless COND; } } The final statement of the loop is linked back to the first statement so that we don't have to exit the loop block and restart it each time through the loop. The "next if" construct is particularly fast because it's linked directly to the implied "last" command. The "if (C) { next; }" construct actually has to bust out of two blocks, and restart the loop block from the outside, where the setjmp for the loop is established. Note that "C && next;" is the exact equivalent of "next if C;" internally. So you aren't forced to write your conditional last to be fast. At the expense of a bit of safety, you could probably link in _setjmp/_longjmp and find a considerable speedup. You might want to give your signal handler an alternate stack in that case, however, and longjmp out of the signal handler that interrupted a longjmp would probably be boomboom time. Larry