From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 12 Apr 93 13:29:34 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!howland.reston.ans.net!noc.n ear.net!inmet!spock!stt@ucbvax.Berkeley.EDU (Tucker Taft) Subject: Re: and then Message-ID: <1993Apr12.132934.2595@inmet.camb.inmet.com> List-Id: In article <1993Apr8.122125.24053@titan.tsd.arlut.utexas.edu> gardner@tsd.arlut.utexas.edu (Don Gardner) writes: >sampson@nosc.mil (Charles H. Sampson) writes: >> My style is to use the boolean operators generally, reserving the >>short-circuit forms to document that the second operand should not be eval- >>uated under some circumstances. > >I humbly suggest that you change your perspective. When I encounter a >non-short-ciruit of the boolean operators I ask why both expressions >_must_ be evaluated; i.e., the short-circuit forms are the default and >the other forms are used only when both expressions must be evaluated. > >Also, I avoid writing functions that have side effects. Since (as >best I can reason at this early hour) both expressions need to be >evaluated only when both have side effects, I rarely use the >non-short-circuit forms. I tend to agree with Don Gardner -- that is, use short-circuit forms unless it is clear that the non-short-circuit form is more efficient or semantically required. However, I have heard heated and somewhat convincing arguments on either side of this. The argument generally seems to reflect the orientation of the debater, more than any absolute better or worse. Personally, I tend to like to have a lot of control over what code gets generated. I rely on the optimizer to eliminate common subexpressions, perform decent global register allocation, and handle all instruction scheduling. I don't rely on the optimizer to do much more than that. This reflects my general suspicion of optimizers (being a compiler writer myself ;-), and my many years of doing machine-level programming. I "think" in terms of "and then" and "or else" -- they just seem more natural in general. I reserve "and" and "or" for combining boolean flags. Some arguments on the other side are: you shouldn't worry about such low-level efficiency concerns before getting the algorithm right; you shouldn't presume you know better than the optimizer what is the best way to evaluate the expression; and you shouldn't sully up a generally abstract algorithm with low-level concerns about best order of evaluation. Certainly on some architectures (e.g. the 680x0), one can compute a boolean value without a branch (using the SETx instructions), and hence it is only the "and then" that forces use of a pipeline-breaking conditional branch. However, on some other architectures, something compiled as: if X < Y and then Y < Z then ... will require, on average, fewer conditional branches than something compiled as: if X < Y and Y < Z then ... Given the equivalence in the absence of side-effects, a clever optimizer (is that an oxymoron? ;-) could choose to generate code either way, given either version written in the source. So if you really believe in your optimizer, it shouldn't make any difference at all! If you don't believe in your optimizer, and the expressions are at all complicated, then it seems prudent to make the decision yourself which is "more efficient" (unfortunately, this can be target dependent) or "more readable" or "more natural," depending which is more important in the current context. Personally, since I find "and then" and "or else" both natural and readable, I rarely end up with just "and" or "or" unless the situation is special in some way. However, those coming to Ada from Pascal (rather than C, for example) might find "and then" and "or else" both ugly and unreadable, and hence their bias would be the other way. In any case, if the efficiency of your system is at the level where "and" vs. "and then" is critical, then either you have done an incredibly good job already of choosing the ultimate algorithm, or you are running extremely close to the edge. On the other hand, if for the given target and the given optimizer, you are wasting several cycles every time you write "and" rather than "and then," I can sympathize with a reviewer who would rather see "and then." However, you should probably double check that "and then" is really more efficient on your architecture and with the given optimizer. It may be that more and more optimizers are performing the permitted transformations between "and" and "and then" (ideally both ways), so you should then pick a uniform style for your projects, reserving one of the two to signify that the situation is somehow "special" (as defined by your project) and use the other of the two systematically in all other situations. In a big project, uniformity and readability often outweigh micro-optimization. The real efficiency gains come from "macro-optimization" via good design, good algorithms, and good data structures. S. Tucker Taft stt@inmet.com Intermetrics, Inc. Cambridge, MA 02138