Will a C/C++ compiler optimise code by reusing a recently calculated function result?Writing Universal memoization function in C++11Can a compiler automatically detect pure functions without the type information about purity?__attribute__((const)) vs __attribute__((pure)) in GNU CFastest way to determine if an integer's square root is an integerWhy does C++ compilation take so long?How can I profile C++ code running on Linux?C++ code file extension? .cc vs .cppWhy do we need virtual functions in C++?Why is this program erroneously rejected by three C++ compilers?Can code that is valid in both C and C++ produce different behavior when compiled in each language?Swift compiler recursive code optimisations (similar to Haskell)C++ code for testing the Collatz conjecture faster than hand-written assembly - why?C++ sqrt function returning truncated (wrong) output

Are there types of animals that can't make the trip to space? (physiologically)

How do we know Nemesis is not a black hole (or neutron star)?

Why the first octet of a MAC address always end with a binary 0?

Writing about real people - not giving offence

Sending mail to the Professor for PhD, after seeing his tweet

Quote to show students don't have to fear making mistakes

What is the point of impeaching Trump?

GPLv3 forces us to make code available, but to who?

Is there a way to replace Smite with Sharpness on a weapon?

Is "Ram married his daughter" ambiguous?

Notation clarity question for a conglomerate of accidentals

Airport Security - advanced check, 4th amendment breach

IEEE 754 square root with Newton-Raphson

Can I bring this power bank on board the aircraft?

What's the correct way to determine turn order in this situation?

Do jackscrews suffer from blowdown?

Does the 'java' command compile Java programs?

Parent asking for money after I moved out

How to say "respectively" in German when listing (enumerating) things

Is there a pattern for handling conflicting function parameters?

Is spot metering just an EV compensation?

Should I be an author on another PhD student's paper if I went to their meetings and gave advice?

How do French and other Romance language speakers cope with the movable do system?

Why do Russians sometimes spell "жирный" (fatty) as "жырный"?



Will a C/C++ compiler optimise code by reusing a recently calculated function result?


Writing Universal memoization function in C++11Can a compiler automatically detect pure functions without the type information about purity?__attribute__((const)) vs __attribute__((pure)) in GNU CFastest way to determine if an integer's square root is an integerWhy does C++ compilation take so long?How can I profile C++ code running on Linux?C++ code file extension? .cc vs .cppWhy do we need virtual functions in C++?Why is this program erroneously rejected by three C++ compilers?Can code that is valid in both C and C++ produce different behavior when compiled in each language?Swift compiler recursive code optimisations (similar to Haskell)C++ code for testing the Collatz conjecture faster than hand-written assembly - why?C++ sqrt function returning truncated (wrong) output






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









1















Suppose I have a function double F(double x) and let's assume for the sake of this example that calls to F are costly.



Suppose I write a function f that calculates the square root of F:



double f(double x)
return sqrt(F(x));



and in a third function sum I calculate the sum of f and F:



double sum(double x)
return F(x) + f(x);



Since I want to minimise calls to F the above code is inefficient compared to e.g.



double sum_2(double x)
double y = F(x);
return y + sqrt(y);



But since I am lazy, or stupid, or want to make my code as clear as possible, I opted for the first definition instead.



Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?



Many thanks.










share|improve this question





















  • 1





    Which compiler? So long as the code produces the same result (and side-effects), the compiler can do what it pleases.

    – Weather Vane
    Mar 28 at 21:14












  • I'm not an expert on such things, but it seems to me it may depend on how F() is defined. Does it have side effects? Can it be inlined?

    – Fred Larson
    Mar 28 at 21:18











  • If you would like to know how compilers see your code, take a look at Compiler Explorer. This shows that F is called two times anyway.

    – ForceBru
    Mar 28 at 21:20







  • 5





    Aside from the interesting academic question of "will it be optimised?", may I suggest you don't write code that relies on the optimisation. If I'm doing code review, and I see an expensive function that looks like it's called more than necessary, that's a huge code smell. I don't want to think about the details of the compiler optimisations, I want to see code that is clear and clearly performant. Remember too, the person reviewing your code may be you in 6 months time.

    – JMAA
    Mar 28 at 21:24






  • 4





    write for readability. Only when you measured you can know if it is worth to compromise for efficiency, but to measure you need a running program first ;)

    – formerlyknownas_463035818
    Mar 28 at 21:26

















1















Suppose I have a function double F(double x) and let's assume for the sake of this example that calls to F are costly.



Suppose I write a function f that calculates the square root of F:



double f(double x)
return sqrt(F(x));



and in a third function sum I calculate the sum of f and F:



double sum(double x)
return F(x) + f(x);



Since I want to minimise calls to F the above code is inefficient compared to e.g.



double sum_2(double x)
double y = F(x);
return y + sqrt(y);



But since I am lazy, or stupid, or want to make my code as clear as possible, I opted for the first definition instead.



Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?



Many thanks.










share|improve this question





















  • 1





    Which compiler? So long as the code produces the same result (and side-effects), the compiler can do what it pleases.

    – Weather Vane
    Mar 28 at 21:14












  • I'm not an expert on such things, but it seems to me it may depend on how F() is defined. Does it have side effects? Can it be inlined?

    – Fred Larson
    Mar 28 at 21:18











  • If you would like to know how compilers see your code, take a look at Compiler Explorer. This shows that F is called two times anyway.

    – ForceBru
    Mar 28 at 21:20







  • 5





    Aside from the interesting academic question of "will it be optimised?", may I suggest you don't write code that relies on the optimisation. If I'm doing code review, and I see an expensive function that looks like it's called more than necessary, that's a huge code smell. I don't want to think about the details of the compiler optimisations, I want to see code that is clear and clearly performant. Remember too, the person reviewing your code may be you in 6 months time.

    – JMAA
    Mar 28 at 21:24






  • 4





    write for readability. Only when you measured you can know if it is worth to compromise for efficiency, but to measure you need a running program first ;)

    – formerlyknownas_463035818
    Mar 28 at 21:26













1












1








1








Suppose I have a function double F(double x) and let's assume for the sake of this example that calls to F are costly.



Suppose I write a function f that calculates the square root of F:



double f(double x)
return sqrt(F(x));



and in a third function sum I calculate the sum of f and F:



double sum(double x)
return F(x) + f(x);



Since I want to minimise calls to F the above code is inefficient compared to e.g.



double sum_2(double x)
double y = F(x);
return y + sqrt(y);



But since I am lazy, or stupid, or want to make my code as clear as possible, I opted for the first definition instead.



Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?



Many thanks.










share|improve this question
















Suppose I have a function double F(double x) and let's assume for the sake of this example that calls to F are costly.



Suppose I write a function f that calculates the square root of F:



double f(double x)
return sqrt(F(x));



and in a third function sum I calculate the sum of f and F:



double sum(double x)
return F(x) + f(x);



Since I want to minimise calls to F the above code is inefficient compared to e.g.



double sum_2(double x)
double y = F(x);
return y + sqrt(y);



But since I am lazy, or stupid, or want to make my code as clear as possible, I opted for the first definition instead.



Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?



Many thanks.







c++ c optimization compiler-optimization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 28 at 21:43







user1892304

















asked Mar 28 at 21:06









user1892304user1892304

2671 gold badge4 silver badges10 bronze badges




2671 gold badge4 silver badges10 bronze badges










  • 1





    Which compiler? So long as the code produces the same result (and side-effects), the compiler can do what it pleases.

    – Weather Vane
    Mar 28 at 21:14












  • I'm not an expert on such things, but it seems to me it may depend on how F() is defined. Does it have side effects? Can it be inlined?

    – Fred Larson
    Mar 28 at 21:18











  • If you would like to know how compilers see your code, take a look at Compiler Explorer. This shows that F is called two times anyway.

    – ForceBru
    Mar 28 at 21:20







  • 5





    Aside from the interesting academic question of "will it be optimised?", may I suggest you don't write code that relies on the optimisation. If I'm doing code review, and I see an expensive function that looks like it's called more than necessary, that's a huge code smell. I don't want to think about the details of the compiler optimisations, I want to see code that is clear and clearly performant. Remember too, the person reviewing your code may be you in 6 months time.

    – JMAA
    Mar 28 at 21:24






  • 4





    write for readability. Only when you measured you can know if it is worth to compromise for efficiency, but to measure you need a running program first ;)

    – formerlyknownas_463035818
    Mar 28 at 21:26












  • 1





    Which compiler? So long as the code produces the same result (and side-effects), the compiler can do what it pleases.

    – Weather Vane
    Mar 28 at 21:14












  • I'm not an expert on such things, but it seems to me it may depend on how F() is defined. Does it have side effects? Can it be inlined?

    – Fred Larson
    Mar 28 at 21:18











  • If you would like to know how compilers see your code, take a look at Compiler Explorer. This shows that F is called two times anyway.

    – ForceBru
    Mar 28 at 21:20







  • 5





    Aside from the interesting academic question of "will it be optimised?", may I suggest you don't write code that relies on the optimisation. If I'm doing code review, and I see an expensive function that looks like it's called more than necessary, that's a huge code smell. I don't want to think about the details of the compiler optimisations, I want to see code that is clear and clearly performant. Remember too, the person reviewing your code may be you in 6 months time.

    – JMAA
    Mar 28 at 21:24






  • 4





    write for readability. Only when you measured you can know if it is worth to compromise for efficiency, but to measure you need a running program first ;)

    – formerlyknownas_463035818
    Mar 28 at 21:26







1




1





Which compiler? So long as the code produces the same result (and side-effects), the compiler can do what it pleases.

– Weather Vane
Mar 28 at 21:14






Which compiler? So long as the code produces the same result (and side-effects), the compiler can do what it pleases.

– Weather Vane
Mar 28 at 21:14














I'm not an expert on such things, but it seems to me it may depend on how F() is defined. Does it have side effects? Can it be inlined?

– Fred Larson
Mar 28 at 21:18





I'm not an expert on such things, but it seems to me it may depend on how F() is defined. Does it have side effects? Can it be inlined?

– Fred Larson
Mar 28 at 21:18













If you would like to know how compilers see your code, take a look at Compiler Explorer. This shows that F is called two times anyway.

– ForceBru
Mar 28 at 21:20






If you would like to know how compilers see your code, take a look at Compiler Explorer. This shows that F is called two times anyway.

– ForceBru
Mar 28 at 21:20





5




5





Aside from the interesting academic question of "will it be optimised?", may I suggest you don't write code that relies on the optimisation. If I'm doing code review, and I see an expensive function that looks like it's called more than necessary, that's a huge code smell. I don't want to think about the details of the compiler optimisations, I want to see code that is clear and clearly performant. Remember too, the person reviewing your code may be you in 6 months time.

– JMAA
Mar 28 at 21:24





Aside from the interesting academic question of "will it be optimised?", may I suggest you don't write code that relies on the optimisation. If I'm doing code review, and I see an expensive function that looks like it's called more than necessary, that's a huge code smell. I don't want to think about the details of the compiler optimisations, I want to see code that is clear and clearly performant. Remember too, the person reviewing your code may be you in 6 months time.

– JMAA
Mar 28 at 21:24




4




4





write for readability. Only when you measured you can know if it is worth to compromise for efficiency, but to measure you need a running program first ;)

– formerlyknownas_463035818
Mar 28 at 21:26





write for readability. Only when you measured you can know if it is worth to compromise for efficiency, but to measure you need a running program first ;)

– formerlyknownas_463035818
Mar 28 at 21:26












3 Answers
3






active

oldest

votes


















8

















Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?




Maybe. Neither language requires such an optimization, and whether they allow it depends on details of the implementation of F(). Generally speaking, different compilers behave differently with respect to this sort of thing.



It is entirely plausible that a compiler would inline function f() into function sum(), which would give it the opportunity to recognize that there are two calls to F(x) contributing to the same result. In that case, if F() has no side effects then it is conceivable that the compiler would emit only a single call to F(), reusing the result.



Particular implementations may have extensions that can be employed to help the compiler come to such a conclusion. Without such an extension being applied to the problem, however, I rate it unlikely that a compiler would emit code that performs just one call to F() and reuses the result.






share|improve this answer

























  • Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

    – Eric Postpischil
    Mar 28 at 23:16







  • 1





    @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

    – John Bollinger
    Mar 29 at 12:03


















2
















What you're describing is called memoization, a form of (usually) run-time caching. While it's possible for this to be implemented in compilers, it's most often not performed in C compilers.



C++ does have a clever workaround for this, using the STL, detailed at this blog post from a few years ago; there's also a slightly more recent SO answer here. It's worth noting that with this approach, the compiler isn't "smartly" inferring that a function's multiple identical results will be reused, but the effect is largely the same.



Some languages, like Haskell, do feature baked-in support for compile-time memoization, but the compiler architecture is fairly different from Clang or GCC/G++.






share|improve this answer






















  • 2





    The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

    – Eric Postpischil
    Mar 28 at 23:04











  • @EricPostpischil this is a good point; do you know any compilers that currently do this?

    – 0xdd
    Mar 29 at 12:46











  • Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

    – Eric Postpischil
    Mar 29 at 14:04


















1
















Many compilers use hints to figure out if a result of a previous function call may be reused. A classical example is:



for (int i=0; i < strlen(str); i++)


Without optimizing this, the complexity of this loop is at least O(n2), but after optimization it can be O(n).



The hints that gcc, clang, and many others can take are __attribute__((pure)) and __attribute__((const)) which are described here. For example, GNU strlen is declared as a pure function.



GCC can detect pure functions, and suggest the programmer which functions should be married pure. In fact, it does that automatically for the following simplistic example:



unsigned my_strlen(const char* str) 

int i=0;
while (str[i])
++i;
return i;


unsigned word_len(const char *str)

for (unsigned i=0 ; i < my_strlen(str); ++i)
if (str[i] == ' ')
return i;

return my_strlen(str);



You can see the compilation result for gcc with -O3 -fno-inline. It calls my_strlen(str) only once in the whole word_len function. Clang 7.0.0 does not seem to perform this optimization.



word_len:
mov rcx, rdi
call my_strlen ; <-- this is the only call (outside any loop)
test eax, eax
je .L7
xor edx, edx
cmp BYTE PTR [rcx], 32
lea rdi, [rdi+1]
jne .L11
jmp .L19
.L12:
add rdi, 1
cmp BYTE PTR [rdi-1], 32
je .L9
.L11:
add edx, 1
cmp eax, edx
jne .L12
.L7:
ret
.L19:
xor edx, edx
.L9:
mov eax, edx
ret





share|improve this answer




























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );














    draft saved

    draft discarded
















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55406843%2fwill-a-c-c-compiler-optimise-code-by-reusing-a-recently-calculated-function-re%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8

















    Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?




    Maybe. Neither language requires such an optimization, and whether they allow it depends on details of the implementation of F(). Generally speaking, different compilers behave differently with respect to this sort of thing.



    It is entirely plausible that a compiler would inline function f() into function sum(), which would give it the opportunity to recognize that there are two calls to F(x) contributing to the same result. In that case, if F() has no side effects then it is conceivable that the compiler would emit only a single call to F(), reusing the result.



    Particular implementations may have extensions that can be employed to help the compiler come to such a conclusion. Without such an extension being applied to the problem, however, I rate it unlikely that a compiler would emit code that performs just one call to F() and reuses the result.






    share|improve this answer

























    • Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

      – Eric Postpischil
      Mar 28 at 23:16







    • 1





      @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

      – John Bollinger
      Mar 29 at 12:03















    8

















    Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?




    Maybe. Neither language requires such an optimization, and whether they allow it depends on details of the implementation of F(). Generally speaking, different compilers behave differently with respect to this sort of thing.



    It is entirely plausible that a compiler would inline function f() into function sum(), which would give it the opportunity to recognize that there are two calls to F(x) contributing to the same result. In that case, if F() has no side effects then it is conceivable that the compiler would emit only a single call to F(), reusing the result.



    Particular implementations may have extensions that can be employed to help the compiler come to such a conclusion. Without such an extension being applied to the problem, however, I rate it unlikely that a compiler would emit code that performs just one call to F() and reuses the result.






    share|improve this answer

























    • Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

      – Eric Postpischil
      Mar 28 at 23:16







    • 1





      @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

      – John Bollinger
      Mar 29 at 12:03













    8














    8










    8










    Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?




    Maybe. Neither language requires such an optimization, and whether they allow it depends on details of the implementation of F(). Generally speaking, different compilers behave differently with respect to this sort of thing.



    It is entirely plausible that a compiler would inline function f() into function sum(), which would give it the opportunity to recognize that there are two calls to F(x) contributing to the same result. In that case, if F() has no side effects then it is conceivable that the compiler would emit only a single call to F(), reusing the result.



    Particular implementations may have extensions that can be employed to help the compiler come to such a conclusion. Without such an extension being applied to the problem, however, I rate it unlikely that a compiler would emit code that performs just one call to F() and reuses the result.






    share|improve this answer














    Would a C/C++ compiler optimise my code anyway by realizing that the value of F(x) can be reused to calculate f(x), as it is done in sum_2?




    Maybe. Neither language requires such an optimization, and whether they allow it depends on details of the implementation of F(). Generally speaking, different compilers behave differently with respect to this sort of thing.



    It is entirely plausible that a compiler would inline function f() into function sum(), which would give it the opportunity to recognize that there are two calls to F(x) contributing to the same result. In that case, if F() has no side effects then it is conceivable that the compiler would emit only a single call to F(), reusing the result.



    Particular implementations may have extensions that can be employed to help the compiler come to such a conclusion. Without such an extension being applied to the problem, however, I rate it unlikely that a compiler would emit code that performs just one call to F() and reuses the result.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 28 at 21:27









    John BollingerJohn Bollinger

    96.7k8 gold badges48 silver badges91 bronze badges




    96.7k8 gold badges48 silver badges91 bronze badges















    • Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

      – Eric Postpischil
      Mar 28 at 23:16







    • 1





      @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

      – John Bollinger
      Mar 29 at 12:03

















    • Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

      – Eric Postpischil
      Mar 28 at 23:16







    • 1





      @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

      – John Bollinger
      Mar 29 at 12:03
















    Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

    – Eric Postpischil
    Mar 28 at 23:16






    Re “I rate it unlikely…”: Apple LLVM 10.0.0 with clang-1000.11.45.5 optimizes sum to have a single call to F if it can see a definition of F it recognizes as pure. Even with a non-pure function (I used ++y; return sin(x) * log(x);, where y was an external int), it generated code to evaluate the pure part once and the impure part (as if) twice.

    – Eric Postpischil
    Mar 28 at 23:16





    1




    1





    @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

    – John Bollinger
    Mar 29 at 12:03





    @EricPostpischil, my estimation of likelihood is based on several things, among them a wild guess about how likely F(), whose evaluation is specified to be costly, is to in fact be pure or to be inlined. Your choice for an example F() is well outside the envelope of functions I have in mind, though I grant that costliness is a relative characteristic.

    – John Bollinger
    Mar 29 at 12:03













    2
















    What you're describing is called memoization, a form of (usually) run-time caching. While it's possible for this to be implemented in compilers, it's most often not performed in C compilers.



    C++ does have a clever workaround for this, using the STL, detailed at this blog post from a few years ago; there's also a slightly more recent SO answer here. It's worth noting that with this approach, the compiler isn't "smartly" inferring that a function's multiple identical results will be reused, but the effect is largely the same.



    Some languages, like Haskell, do feature baked-in support for compile-time memoization, but the compiler architecture is fairly different from Clang or GCC/G++.






    share|improve this answer






















    • 2





      The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

      – Eric Postpischil
      Mar 28 at 23:04











    • @EricPostpischil this is a good point; do you know any compilers that currently do this?

      – 0xdd
      Mar 29 at 12:46











    • Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

      – Eric Postpischil
      Mar 29 at 14:04















    2
















    What you're describing is called memoization, a form of (usually) run-time caching. While it's possible for this to be implemented in compilers, it's most often not performed in C compilers.



    C++ does have a clever workaround for this, using the STL, detailed at this blog post from a few years ago; there's also a slightly more recent SO answer here. It's worth noting that with this approach, the compiler isn't "smartly" inferring that a function's multiple identical results will be reused, but the effect is largely the same.



    Some languages, like Haskell, do feature baked-in support for compile-time memoization, but the compiler architecture is fairly different from Clang or GCC/G++.






    share|improve this answer






















    • 2





      The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

      – Eric Postpischil
      Mar 28 at 23:04











    • @EricPostpischil this is a good point; do you know any compilers that currently do this?

      – 0xdd
      Mar 29 at 12:46











    • Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

      – Eric Postpischil
      Mar 29 at 14:04













    2














    2










    2









    What you're describing is called memoization, a form of (usually) run-time caching. While it's possible for this to be implemented in compilers, it's most often not performed in C compilers.



    C++ does have a clever workaround for this, using the STL, detailed at this blog post from a few years ago; there's also a slightly more recent SO answer here. It's worth noting that with this approach, the compiler isn't "smartly" inferring that a function's multiple identical results will be reused, but the effect is largely the same.



    Some languages, like Haskell, do feature baked-in support for compile-time memoization, but the compiler architecture is fairly different from Clang or GCC/G++.






    share|improve this answer















    What you're describing is called memoization, a form of (usually) run-time caching. While it's possible for this to be implemented in compilers, it's most often not performed in C compilers.



    C++ does have a clever workaround for this, using the STL, detailed at this blog post from a few years ago; there's also a slightly more recent SO answer here. It's worth noting that with this approach, the compiler isn't "smartly" inferring that a function's multiple identical results will be reused, but the effect is largely the same.



    Some languages, like Haskell, do feature baked-in support for compile-time memoization, but the compiler architecture is fairly different from Clang or GCC/G++.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 28 at 21:36

























    answered Mar 28 at 21:27









    0xdd0xdd

    2042 silver badges15 bronze badges




    2042 silver badges15 bronze badges










    • 2





      The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

      – Eric Postpischil
      Mar 28 at 23:04











    • @EricPostpischil this is a good point; do you know any compilers that currently do this?

      – 0xdd
      Mar 29 at 12:46











    • Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

      – Eric Postpischil
      Mar 29 at 14:04












    • 2





      The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

      – Eric Postpischil
      Mar 28 at 23:04











    • @EricPostpischil this is a good point; do you know any compilers that currently do this?

      – 0xdd
      Mar 29 at 12:46











    • Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

      – Eric Postpischil
      Mar 29 at 14:04







    2




    2





    The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

    – Eric Postpischil
    Mar 28 at 23:04





    The question does not describe memoization. Memoization is one technique that could speed up computation, possibly in the circumstances described in the question, but the question asks about reusing previously calculated results in general, not memoization. It is much more likely that a compiler might recognize that, in sum, F(x) is calculated both directly and within the call to f(x) and hence might generate code to evaluate F(x) only once and reuse the result.

    – Eric Postpischil
    Mar 28 at 23:04













    @EricPostpischil this is a good point; do you know any compilers that currently do this?

    – 0xdd
    Mar 29 at 12:46





    @EricPostpischil this is a good point; do you know any compilers that currently do this?

    – 0xdd
    Mar 29 at 12:46













    Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

    – Eric Postpischil
    Mar 29 at 14:04





    Do what, recognize that F(x) is evaluated twice? As noted in my comment on John Bollinger’s answer, Clang does, and I expect other good quality compilers do too.

    – Eric Postpischil
    Mar 29 at 14:04











    1
















    Many compilers use hints to figure out if a result of a previous function call may be reused. A classical example is:



    for (int i=0; i < strlen(str); i++)


    Without optimizing this, the complexity of this loop is at least O(n2), but after optimization it can be O(n).



    The hints that gcc, clang, and many others can take are __attribute__((pure)) and __attribute__((const)) which are described here. For example, GNU strlen is declared as a pure function.



    GCC can detect pure functions, and suggest the programmer which functions should be married pure. In fact, it does that automatically for the following simplistic example:



    unsigned my_strlen(const char* str) 

    int i=0;
    while (str[i])
    ++i;
    return i;


    unsigned word_len(const char *str)

    for (unsigned i=0 ; i < my_strlen(str); ++i)
    if (str[i] == ' ')
    return i;

    return my_strlen(str);



    You can see the compilation result for gcc with -O3 -fno-inline. It calls my_strlen(str) only once in the whole word_len function. Clang 7.0.0 does not seem to perform this optimization.



    word_len:
    mov rcx, rdi
    call my_strlen ; <-- this is the only call (outside any loop)
    test eax, eax
    je .L7
    xor edx, edx
    cmp BYTE PTR [rcx], 32
    lea rdi, [rdi+1]
    jne .L11
    jmp .L19
    .L12:
    add rdi, 1
    cmp BYTE PTR [rdi-1], 32
    je .L9
    .L11:
    add edx, 1
    cmp eax, edx
    jne .L12
    .L7:
    ret
    .L19:
    xor edx, edx
    .L9:
    mov eax, edx
    ret





    share|improve this answer































      1
















      Many compilers use hints to figure out if a result of a previous function call may be reused. A classical example is:



      for (int i=0; i < strlen(str); i++)


      Without optimizing this, the complexity of this loop is at least O(n2), but after optimization it can be O(n).



      The hints that gcc, clang, and many others can take are __attribute__((pure)) and __attribute__((const)) which are described here. For example, GNU strlen is declared as a pure function.



      GCC can detect pure functions, and suggest the programmer which functions should be married pure. In fact, it does that automatically for the following simplistic example:



      unsigned my_strlen(const char* str) 

      int i=0;
      while (str[i])
      ++i;
      return i;


      unsigned word_len(const char *str)

      for (unsigned i=0 ; i < my_strlen(str); ++i)
      if (str[i] == ' ')
      return i;

      return my_strlen(str);



      You can see the compilation result for gcc with -O3 -fno-inline. It calls my_strlen(str) only once in the whole word_len function. Clang 7.0.0 does not seem to perform this optimization.



      word_len:
      mov rcx, rdi
      call my_strlen ; <-- this is the only call (outside any loop)
      test eax, eax
      je .L7
      xor edx, edx
      cmp BYTE PTR [rcx], 32
      lea rdi, [rdi+1]
      jne .L11
      jmp .L19
      .L12:
      add rdi, 1
      cmp BYTE PTR [rdi-1], 32
      je .L9
      .L11:
      add edx, 1
      cmp eax, edx
      jne .L12
      .L7:
      ret
      .L19:
      xor edx, edx
      .L9:
      mov eax, edx
      ret





      share|improve this answer





























        1














        1










        1









        Many compilers use hints to figure out if a result of a previous function call may be reused. A classical example is:



        for (int i=0; i < strlen(str); i++)


        Without optimizing this, the complexity of this loop is at least O(n2), but after optimization it can be O(n).



        The hints that gcc, clang, and many others can take are __attribute__((pure)) and __attribute__((const)) which are described here. For example, GNU strlen is declared as a pure function.



        GCC can detect pure functions, and suggest the programmer which functions should be married pure. In fact, it does that automatically for the following simplistic example:



        unsigned my_strlen(const char* str) 

        int i=0;
        while (str[i])
        ++i;
        return i;


        unsigned word_len(const char *str)

        for (unsigned i=0 ; i < my_strlen(str); ++i)
        if (str[i] == ' ')
        return i;

        return my_strlen(str);



        You can see the compilation result for gcc with -O3 -fno-inline. It calls my_strlen(str) only once in the whole word_len function. Clang 7.0.0 does not seem to perform this optimization.



        word_len:
        mov rcx, rdi
        call my_strlen ; <-- this is the only call (outside any loop)
        test eax, eax
        je .L7
        xor edx, edx
        cmp BYTE PTR [rcx], 32
        lea rdi, [rdi+1]
        jne .L11
        jmp .L19
        .L12:
        add rdi, 1
        cmp BYTE PTR [rdi-1], 32
        je .L9
        .L11:
        add edx, 1
        cmp eax, edx
        jne .L12
        .L7:
        ret
        .L19:
        xor edx, edx
        .L9:
        mov eax, edx
        ret





        share|improve this answer















        Many compilers use hints to figure out if a result of a previous function call may be reused. A classical example is:



        for (int i=0; i < strlen(str); i++)


        Without optimizing this, the complexity of this loop is at least O(n2), but after optimization it can be O(n).



        The hints that gcc, clang, and many others can take are __attribute__((pure)) and __attribute__((const)) which are described here. For example, GNU strlen is declared as a pure function.



        GCC can detect pure functions, and suggest the programmer which functions should be married pure. In fact, it does that automatically for the following simplistic example:



        unsigned my_strlen(const char* str) 

        int i=0;
        while (str[i])
        ++i;
        return i;


        unsigned word_len(const char *str)

        for (unsigned i=0 ; i < my_strlen(str); ++i)
        if (str[i] == ' ')
        return i;

        return my_strlen(str);



        You can see the compilation result for gcc with -O3 -fno-inline. It calls my_strlen(str) only once in the whole word_len function. Clang 7.0.0 does not seem to perform this optimization.



        word_len:
        mov rcx, rdi
        call my_strlen ; <-- this is the only call (outside any loop)
        test eax, eax
        je .L7
        xor edx, edx
        cmp BYTE PTR [rcx], 32
        lea rdi, [rdi+1]
        jne .L11
        jmp .L19
        .L12:
        add rdi, 1
        cmp BYTE PTR [rdi-1], 32
        je .L9
        .L11:
        add edx, 1
        cmp eax, edx
        jne .L12
        .L7:
        ret
        .L19:
        xor edx, edx
        .L9:
        mov eax, edx
        ret






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 29 at 21:27

























        answered Mar 28 at 22:43









        Michael VekslerMichael Veksler

        6,2321 gold badge9 silver badges26 bronze badges




        6,2321 gold badge9 silver badges26 bronze badges































            draft saved

            draft discarded















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55406843%2fwill-a-c-c-compiler-optimise-code-by-reusing-a-recently-calculated-function-re%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript