Jump to content

Do compilers combine math operations?

TickleForce
Go to solution Solved by laxer,

Since no one has really successfully answered this question I will do it.

 

Yes the compiler will optimize the code, It is known as Constant Folding.

 

How you program it is personal preference. The performance is negligible when it is processed through the parser. (It will create one fewer node)

 

If you follow the holy bible of programming(Code Complete by McConnell)

 

It is better to write it out as the code is generally easier to follow.

 

In all honesty, absolutely no one cares about seconds saved during compiling. It is more important to make the code readable than it is to compile quickly.

Let's say I have something like this in my code:

int a = 5 * 10;

Will the compiler automatically combine the operations and make "int a = 50" instead of calculating the result every time? The reason I ask is because sometimes it is easier to remember why I used a particular number if I leave the operations intact, but at the same time I want to make my code as efficient as possible, especially if something like this is inside a loop. I'm pretty sure most C/C++ compilers would do this, but what about interpreted languages like Java or Python?

Link to comment
Share on other sites

Link to post
Share on other sites

think if you put this in a loop it will keep calculating it, because if you had for example a changing variable, you want your a variable to keep up with that one right?

@TickleForce 

"We're all in this together, might as well be friends" Tom, Toonami.

 

mini eLiXiVy: my open source 65% mechanical PCB, a build log, PCB anatomy and discussing open source licenses: https://linustechtips.com/topic/1366493-elixivy-a-65-mechanical-keyboard-build-log-pcb-anatomy-and-how-i-open-sourced-this-project/

 

mini_cardboard: a 4% keyboard build log and how keyboards workhttps://linustechtips.com/topic/1328547-mini_cardboard-a-4-keyboard-build-log-and-how-keyboards-work/

Link to comment
Share on other sites

Link to post
Share on other sites

No the compiler does not do the operations

They are all run when the program starts, the compiler just interprets it to binary

NEW PC build: Blank Heaven   minimalist white and black PC     Old S340 build log "White Heaven"        The "LIGHTCANON" flashlight build log        Project AntiRoll (prototype)        Custom speaker project

Spoiler

Ryzen 3950X | AMD Vega Frontier Edition | ASUS X570 Pro WS | Corsair Vengeance LPX 64GB | NZXT H500 | Seasonic Prime Fanless TX-700 | Custom loop | Coolermaster SK630 White | Logitech MX Master 2S | Samsung 980 Pro 1TB + 970 Pro 512GB | Samsung 58" 4k TV | Scarlett 2i4 | 2x AT2020

 

Link to comment
Share on other sites

Link to post
Share on other sites

No the compiler does not do the operations

They are all run when the program starts, the compiler just interprets it to binary

 

The compiler WILL perform optimizations. Chances are it will see that a simple math expression like this will always evaluate to the same result, and so just store that result in the assembly.

Link to comment
Share on other sites

Link to post
Share on other sites

The question is, why wouldn't YOU combine the operations?

Sometime leaving the operations intact helps to self-document the code. Also, sometimes the operations to perform are too complicated to calculate in my head and it's faster to type it out than to calculate the result.

 

 

The compiler WILL perform optimizations. Chances are it will see that a simple math expression like this will always evaluate to the same result, and so just store that result in the assembly.

This is what I was thinking. If the result of an operation is always the same and is known at compile-time, then I suspect that most compilers would just store the result. I'm just wondering if someone here knows for sure.

Link to comment
Share on other sites

Link to post
Share on other sites

The compiler WILL perform optimizations. Chances are it will see that a simple math expression like this will always evaluate to the same result, and so just store that result in the assembly.

I'm pretty sure all math is done in real time in C++

http://www.tantalon.com/pete/cppopt/main.htm

optimisations are done for things like const

NEW PC build: Blank Heaven   minimalist white and black PC     Old S340 build log "White Heaven"        The "LIGHTCANON" flashlight build log        Project AntiRoll (prototype)        Custom speaker project

Spoiler

Ryzen 3950X | AMD Vega Frontier Edition | ASUS X570 Pro WS | Corsair Vengeance LPX 64GB | NZXT H500 | Seasonic Prime Fanless TX-700 | Custom loop | Coolermaster SK630 White | Logitech MX Master 2S | Samsung 980 Pro 1TB + 970 Pro 512GB | Samsung 58" 4k TV | Scarlett 2i4 | 2x AT2020

 

Link to comment
Share on other sites

Link to post
Share on other sites

I'm pretty sure all math is done in real time in C++

http://www.tantalon.com/pete/cppopt/main.htm

optimisations are done for things like const

#include <stdio.h>void main() {  int a = 5 * 10;  printf("%d", a);}

This produces the instruction "move 50 into the edx register":

mov $0x32,%edx

There is no need to perform a math operation that is the same every time, thus the compiler optimizes it away. I would guess that interpreted languages perform the same type of optimization as this is basic stuff to deal with for a compiler, JIT or otherwise.

Link to comment
Share on other sites

Link to post
Share on other sites

The question is, why wouldn't YOU combine the operations?

seconds = days * 24 * 60 * 60

when you want your numbers to be meaningful

Link to comment
Share on other sites

Link to post
Share on other sites

Sometime leaving the operations intact helps to self-document the code. Also, sometimes the operations to perform are too complicated to calculate in my head and it's faster to type it out than to calculate the result.

 

 

This is what I was thinking. If the result of an operation is always the same and is known at compile-time, then I suspect that most compilers would just store the result. I'm just wondering if someone here knows for sure.

 

Then document the operation via comment, and use a calculator to do the operation beforehand and hard-code it.

 

For such operations, I'm pretty sure all modern compilers do that.

Link to comment
Share on other sites

Link to post
Share on other sites

seconds = days * 24 * 60 * 60

when you want your numbers to be meaningful

 

 

Okay, but then comments exist for a reason.

Link to comment
Share on other sites

Link to post
Share on other sites

>>> def f():...     s = 5 * 10...     return s...>>> import dis>>> dis.dis(f)  2           0 LOAD_CONST               3 (50)              3 STORE_FAST               0 (s)  3           6 LOAD_FAST                0 (s)              9 RETURN_VALUE>>>

Python optimizes it and if they do, every other language must.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

Then document the operation via comment, and use a calculator to do the operation beforehand and hard-code it.

Okay, but then comments exist for a reason.

would anyone prefer the second function over the first?

code should be readable whenever possible

function average(numbers){	total = 0	foreach(number in numbers)	{		total = total + number	}	return total / count(numbers)}// prit: array of numbers// return the average of pritfunction lzx(prit){	praprepro = 0	foreach(luhw in prit)	{		praprepro = praprepro + luhw	}	return praprepro / count(prit)}
Link to comment
Share on other sites

Link to post
Share on other sites

 

would anyone prefer the second function over the first?

code should be readable whenever possible

function average(numbers){	total = 0	foreach(number in numbers)	{		total = total + number	}	return total / count(numbers)}// prit: array of numbers// return the average of pritfunction lzx(prit){	praprepro = 0	foreach(luhw in prit)	{		praprepro = praprepro + luhw	}	return praprepro / count(prit)}

 

Please.

Link to comment
Share on other sites

Link to post
Share on other sites

 

would anyone prefer the second function over the first?

code should be readable whenever possible

function average(numbers){	total = 0	foreach(number in numbers)	{		total = total + number	}	return total / count(numbers)}// prit: array of numbers// return the average of pritfunction lzx(prit){	praprepro = 0	foreach(luhw in prit)	{		praprepro = praprepro + luhw	}	return praprepro / count(prit)}

 

What are you even talking about? I was considering optimization, not code readability.

 

For example,

int something = 86400; //or 24*60*60

Which is optimized, in compilation and runtime, and also perfectly "readable".

Link to comment
Share on other sites

Link to post
Share on other sites

Please.

i honestly don't see the difference between the dumb-named function and hardcoding a meaningless number

 

What are you even talking about? I was considering optimization, not code readability.

 

For example,

int something = 86400; //or 24*60*60

Which is optimized, in compilation and runtime, and also perfectly "readable".

24*60*60 gets optimised, so it's just as fast

your code leaves space for errors (if that number gets changed for an error, good luck finding that out) and i need to read an instruction AND a comment to understand it. unnecessary and again, redundant

Link to comment
Share on other sites

Link to post
Share on other sites

i honestly don't see the difference between the dumb-named function and hardcoding a meaningless number

 

24*60*60 gets optimised, so it's just as fast

your code leaves space for errors (if that number gets changed for an error, good luck finding that out) and i need to read an instruction AND a comment to understand it. unnecessary and again, redundant

 

Or, use a constant to store the value(s). Self documenting. Version control and unit test to avoid unintentional logical errors.

Link to comment
Share on other sites

Link to post
Share on other sites

Yes, of course it will be optimized in compile time. Simple math operations of const values are calculated beforehand

Link to comment
Share on other sites

Link to post
Share on other sites

i honestly don't see the difference between the dumb-named function and hardcoding a meaningless number

 

24*60*60 gets optimised, so it's just as fast

your code leaves space for errors (if that number gets changed for an error, good luck finding that out) and i need to read an instruction AND a comment to understand it. unnecessary and again, redundant

 

Did you know that 24*60*60 has to be evaluated during compilation, which slows down compile-time, rather than 86400? Compile-time for some software can get fairly large, so such optimizations are beneficial.

 

I am not saying that my suggestion is perfect. This can be better designed with constants, but within the scope of the OP's question, that is sufficient. I don't know what kind of software he's making and neither do you. 

Link to comment
Share on other sites

Link to post
Share on other sites

Did you know that 24*60*60 has to be evaluated during compilation, which slows down compile-time, rather than 86400? Compile-time for some software can get fairly large, so such optimizations are beneficial.

i really, really don't think so. a couple multiplications won't affect compile time in any meaningful way, even if i had a million "multiplicated constants" spread all over my source

 

Or, use a constant to store the value(s). Self documenting. Version control and unit test to avoid unintentional logical errors.

if you would define the constant as a precomputed value, the argument is still the same

Link to comment
Share on other sites

Link to post
Share on other sites

if you would define the constant as a precomputed value, the argument is still the same

 

Okay, you win. Happy?

Link to comment
Share on other sites

Link to post
Share on other sites

Did you know that 24*60*60 has to be evaluated during compilation, which slows down compile-time, rather than 86400? Compile-time for some software can get fairly large, so such optimizations are beneficial.

The actual difference in compilation time is probably negligible. The amount of time a multiplication takes is on the order of nanoseconds on a modern CPU

 

Writing it in assembly would also speed up compilation time... not sure that saving time on compilation is really an argument for making your code into spaghetti.

Link to comment
Share on other sites

Link to post
Share on other sites

The compiler could also do some shifting if it wanted to.

Link to comment
Share on other sites

Link to post
Share on other sites

Did you know that 24*60*60 has to be evaluated during compilation, which slows down compile-time, rather than 86400? Compile-time for some software can get fairly large, so such optimizations are beneficial.

 

I am not saying that my suggestion is perfect. This can be better designed with constants, but within the scope of the OP's question, that is sufficient. I don't know what kind of software he's making and neither do you. 

"Slows down compile time". Yes, only if you use some crappy make system and/or build tools. If you learn the compilers and just use a simple batch file to do run the commands for the compiler it takes an instant, even with large files. People like to make a big deal out of compiling, yet it's trivial on modern systems.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×