5 ms·
> Don't try to out-clever the compiler. You might be able to do it, but there's no guarantee that tomorrow's compiler update won't be smarter than your today's
by ajanuary 12y ago
> Don't try to out-clever the compiler. You might be able to do it, but there's no guarantee that tomorrow's compiler update won't be smarter than your today's workaround, leaving you with code that is both "weird" and slow.
I think that's definitely true in the general case.
However, for a 19 line library whose focus is "fast retrying" where the goto construct is "goto beginning of function", I don't think it's really hugely "weird".
In this case it's also extremely unlikely to get slower.
- kstrauser 12y ago> However, for a 19 line library whose focus is "fast retrying" where the goto construct is "goto beginning of function", I don't think it's really hugely "weird". Fast retrying of network operations, generally. This optimization should save a few nanoseconds per call to a network service that might take a few hundred or thousand milliseconds. When the payoff is so vanishingly tiny as to be immeasurable, I'd take idiomatic code over clever interpreter-specific optimizations any day.
- thaumaturgy 12y agoThe most interesting thing about this thread (and the one on Github) is that so many programmers are now incapable of discerning between good use of goto, and bad use of goto. "goto is bad" has become a hard-line rule that programmers follow now without question or consideration. Here's the current version of the retry function: function retry($retries, callable $fn) { beginning: try { return $fn(); } catch (\Exception $e) { if (!$retries) { throw new FailingTooHardException('', 0, $e); } $retries--; goto beginning; } } Now, throw out everything you know about gotos for a moment, and really look at the code. Is it unreadable? Hard to understand? Does it do anything wrong other than violate the hard rule, "thou shalt not goto"? And if gotos are inherently, irredeemably evil, then why do we use switch statements? Because each case label in a switch statement is a goto. Dijsktra in his original letter condemned the "unbridled" use of gotos. At that time, there was -- according to Dijsktra -- a growing trend in programming, where gotos were used to jump from one area of a program to the next, and into and out of loops, making the program flow very difficult to follow. (A good review of Dijsktra's "Goto considered harmful" is at http://david.tribble.com/text/goto.html http://david.tribble.com/text/goto.html .) Dijsktra proposed abolishing goto altogether as a knee-jerk reaction to the habits of that era's programmers, but only because in his view it was too great of a temptation for abuse. I doubt Dijsktra would have even raised an eyebrow at the use of goto in the example above.
- kstrauser 12y agoIt's not terrible, but it's obfuscating the fact that it's really just a do/while loop. It's not obvious at a glance what's happening because most peoples' eyes expect to see a for, or a do, or a while when they're trying to spot a loop. It's also bad because you're effectively lying to the interpreter. Suppose a future optimization involves some super efficient loop unrolling or such. Well, too bad: because you've hand-rolled your own looping construct, the compiler probably won't be able to use it. In general, just write idiomatic code that other programmers can readily work with. If (and only if!) a profiler identifies a problem, tweak just that part of the code. Leave liberal comments about what and why you did so that future programmers can evaluate whether your trickery is still worthwhile.
- thaumaturgy 12y agoIt really isn't that unclear, to me at least. If it's unclear to other programmers, I think that's only because gotos have fallen so far out of fashion that they look alien now. That's really a shame, because there are cases for the elegant use of goto, and I think the retry() code above is one of them. You argued earlier that there was no point in making this optimization in the first place, since it probably wasn't contributing a significant delay in the application (which I disagree with on the grounds that we don't know what retry() might be used for), but now you're saying that it shouldn't be done this way because the compiler might later do a better job of optimizing a standard loop. As others have pointed out, there are some good reasons not to expect PHP's bytecode runtime to match the optimizations of other software compilers. Without knowing in advance exactly how many times the function call embedded in retry() will be repeated -- which seems pretty unlikely -- there's no good way for the compiler to unroll the loop more efficiently than has already been done here with the straightforward application of a goto. Sure, in general, don't be too clever. (Rather, "don't be cruel to future programmers".) I agree. But, I think there's a far greater danger of programmers blindly following guidelines like "don't use goto" without consideration. So while there probably isn't a good argument for writing this function this way, there also isn't a good argument against it -- which is what makes all of the discussion around it so funny.