Why are compilers so stupid?

前端 未结 29 1797
借酒劲吻你
借酒劲吻你 2020-11-29 18:07

I always wonder why compilers can\'t figure out simple things that are obvious to the human eye. They do lots of simple optimizations, but never something even a little bit

相关标签:
29条回答
  • 2020-11-29 18:32

    On your first example, it's an optimization that only works if the value is zero. The extra if statement in the compiler needed to look for this one rarely-seen clause may just not be worth it (since it'll have to check for this on every single variable). Furthermore, what about this:

    int x = 1;
    int y = 1;
    int z = x - y;
    for (int i = 0; i < 100 * 1000 * 1000 * 1000; ++i) {
        z += z + z + z + z + z;
    }
    System.out.println(z);
    

    This is still obviously the same thing, but now there's an extra case we have to code for in the compiler. There's just an infinite amount of ways that it can end up being zero that aren't worth coding in for, and I guess you could say that if you're going to have one of them you'd might as well have them all.

    Some optimizations do take care of the second example you have posted, but I think I've seen it more in functional languages and not so much Java. The big thing that makes it hard in newer languages is monkey-patching. Now += can have a side-effect that means if we optimize it out, it's potentially wrong (e.g. adding functionality to += that prints out the current value will mean a different program altogether).

    But it comes down to the same thing all over again: there's just too many cases you'd have to look for to make sure no side effects are being performed that will potentially alter the final program's state.

    It's just easier to take an extra moment and make sure what you're writing is what you really want the computer to do. :)

    0 讨论(0)
  • 2020-11-29 18:33

    Because we're just not there yet. You could just as easily have asked, "why do I still need to write programs... why can't I just feed in the requirements document and have the computer write the application for me?"

    Compiler writers spend time on the little things, because those are the types of things that application programmers tend to miss.

    Also, they cannot assume too much (maybe your loop was some kind of ghetto time delay or something)?

    0 讨论(0)
  • 2020-11-29 18:38

    In my opinion, I don't believe it's the job of the compiler to fix what is, honestly, bad coding. You have, quite explicitly, told the compiler you want that first loop executed. It's the same as:

    x = 0
    sleep 6 // Let's assume this is defined somewhere.
    print x
    

    I wouldn't want the compiler removing my sleep statement just because it did nothing. You may argue that the sleep statement is an explicit request for a delay whereas your example is not. But then you will be allowing the compiler to make very high-level decisions about what your code should do, and I believe that to be a bad thing.

    Code, and the compiler that processes it, are tools and you need to be a tool-smith if you want to use them effectively. How many 12" chainsaws will refuse to try cut down a 30" tree? How many drills will automatically switch to hammer mode if they detect a concrete wall?

    None, I suspect, and this is because the cost of designing this into the product would be horrendous for a start. But, more importantly, you shouldn't be using drills or chainsaws if you don't know what you're doing. For example: if you don't know what kickback is (a very easy way for a newbie to take off their arm), stay away from chainsaws until you do.

    I'm all for allowing compilers to suggest improvements but I'd rather maintain the control myself. It should not be up to the compiler to decide unilaterally that a loop is unnecessary.

    For example, I've done timing loops in embedded systems where the clock speed of the CPU is known exactly but no reliable timing device is available. In that case, you can calculate precisely how long a given loop will take and use that to control how often things happen. That wouldn't work if the compiler (or assembler in that case) decided my loop was useless and optimized it out of existence.

    Having said that, let me leave you with an old story of a VAX FORTRAN compiler that was undergoing a benchmark for performance and it was found that it was many orders of magnitude faster than its nearest competitor.

    It turns out the compiler noticed that the result of the benchmark loops weren't being used anywhere else and optimized the loops into oblivion.

    0 讨论(0)
  • 2020-11-29 18:39

    Speaking from a C/C++ point of view:

    Your first example will be optimized by most compilers. If the java-compiler from Sun really executes this loop it's the compilers fault, but take my word that any post 1990 C, C++ or Fortran-compiler completely eliminates such a loop.

    Your second example can't be optimized in most languages because memory allocation happens as a side-effect of concatenating the strings together. If a compiler would optimize the code the pattern of memory allocation would change, and this could lead to effects that the programmer tries to avoid. Memory fragmentation and related problems are issues that embedded programmers still face every day.

    Overall I'm satisfied with the optimizations compilers can do these days.

    0 讨论(0)
  • 2020-11-29 18:41

    Compilers that can do strict-aliasing optimizations, will optimize first example out. See here.

    Second example can't be optimized because the slowest part here is memory allocation/reallocation and operator+= is redefined into a function that does the memory stuff. Different implementations of strings use different allocation strategies.

    I myself also would rather like to have malloc(100000) than thousand malloc(100) too when doing s += "s"; but right now that thing is out of scope of compilers and has to be optimized by people. This is what D language tries to solve by introducing pure functions.

    As mentioned here in other answers, perl does second example in less than a second because it allocates more memory than requested just in case more memory will be needed later.

    0 讨论(0)
  • 2020-11-29 18:42

    The meaning of your two examples is pointless, useless and only made to fool the compiler.

    The compiler is not capable (and should not be) to see the meaning of a method, a loop or a program. That is where you get into the picture. You create a method for a certain functionality/meaning, no matter how stupid it is. It's the same case for simple problems or extreme complex programs.

    In your case the compiler might optimize it, because it "thinks" it should be optimized in another way but why stay there?

    Extreme other situation. We have a smart compiler compiling Windows. Tons of code to compile. But if it's smart, it boils it down to 3 lines of code...

    "starting windows"
    "enjoy freecell/solitaire"
    "shutting down windows"
    

    The rest of the code is obsolete, because it's never used, touched, accessed. Do we really want that?

    0 讨论(0)
提交回复
热议问题