Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: next if C VS if (C) { next } Message-ID: <1991May23.050211.5399@jpl-devvax.jpl.nasa.gov> Date: 23 May 91 05:02:11 GMT References: <1991May22.021106.13838@convex.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 63 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