Well since we don’t have a topic for today’s entry how about a bit of Q&A.
This has to do with multiplication and assignment operators.
So which of the following is faster and/or equivalent and with which primitive numeric types:
// where x is a numeric primitive
result = x * x * x * x;
result = ((x = x * x) * x);
My guess is that the second is faster as its operations break down to two assignments and two multiplications, whereas the first has 3 multiplications and one assignment. This seems straight-forward, however I wonder if those parentheses have any sort of impact when the compiler parses the second statement. Thoughts?
For the Number datatype it doesn’t make the slightest difference; though for float, int, uint, long, ulong it will, float4 might as well (float/float4 are planned additions to interact with molehill APIs). It has nothing to do with what happens in the VM, though, it’s the compiler. So if someone creates one for regular AS3 (haXe doesn’t count) then it won’t matter.
The problem is that MXMLC is like an underpaid monkey. Any statement more complex than two variables and one operator will be compiled as though there is only one datatype in the entire language (using the generic add, multiply, subtract, etc. operators), mostly leftover from AS2 when there really was only one real datatype; partly because Adobe has been incredibly lazy and not told anyone to work on the compiler, apparently.
On the bright side, nanoJIT is fairly advanced and can fix some of the issues. The large majority are ignored though, because it’s difficult to parse the bytecode at a high level using only an array of bytes and lazy stack counting / verification.
I am working on a post-compile optimizer that handles it at a much higher level, going so far as to be a slim implementation of tamarin itself but bulkier (and more memory heavy due to using a LinkedList for the opcodes) than nJIT. I’ve taken a brief hiatus from programming due to stress though, but should have some demos up by October.
Sorry for the lack of clarity in my earlier snippet. What I meant was
// where x is a numeric primitive
var x:Number = 10; // or x:int = 10 or x:uint = 10
result = x * x * x * x;
result = ((x = x * x) * x);
So your second set of test expressions would have been my target test case.
Nonetheless your results were insightful even if somewhat disappointing. One would think that an assignment operation (what I assume amounts to a simple mov op at the machine level) would be much faster than multiplication. Doesn't appear to be the case...
And another question…why is it my code snippets aren’t nicely color-coded like yours. Using the pre tag with the lang attribute set to “actionscript3” doesn’t seem to work.
#1 by Zzloba on August 15th, 2011 ·
:)
#2 by guest on August 15th, 2011 ·
Aaaagrhhhh you’ve ruined my week! =)
#3 by Erik on August 16th, 2011 ·
I think you could optimize this by casting to int.
#4 by dimuMurray on August 21st, 2011 ·
Well since we don’t have a topic for today’s entry how about a bit of Q&A.
This has to do with multiplication and assignment operators.
So which of the following is faster and/or equivalent and with which primitive numeric types:
#5 by jackson on August 22nd, 2011 ·
Consider
x==10
:So these are quite different expressions. How about this instead?
For that version, I get these results on Windows 7 with a Xeon 3530:
So the times are virtually the same. If you’re interested, here’s the test code:
#6 by skyboy on August 22nd, 2011 ·
For the Number datatype it doesn’t make the slightest difference; though for float, int, uint, long, ulong it will, float4 might as well (float/float4 are planned additions to interact with molehill APIs). It has nothing to do with what happens in the VM, though, it’s the compiler. So if someone creates one for regular AS3 (haXe doesn’t count) then it won’t matter.
The problem is that MXMLC is like an underpaid monkey. Any statement more complex than two variables and one operator will be compiled as though there is only one datatype in the entire language (using the generic add, multiply, subtract, etc. operators), mostly leftover from AS2 when there really was only one real datatype; partly because Adobe has been incredibly lazy and not told anyone to work on the compiler, apparently.
On the bright side, nanoJIT is fairly advanced and can fix some of the issues. The large majority are ignored though, because it’s difficult to parse the bytecode at a high level using only an array of bytes and lazy stack counting / verification.
I am working on a post-compile optimizer that handles it at a much higher level, going so far as to be a slim implementation of tamarin itself but bulkier (and more memory heavy due to using a LinkedList for the opcodes) than nJIT. I’ve taken a brief hiatus from programming due to stress though, but should have some demos up by October.
#7 by jackson on August 22nd, 2011 ·
Thanks for the helpful information. Your project sounds really cool too.
Take care and let me know when you have something ready to show. :)
#8 by dimuMurray on August 22nd, 2011 ·
Sorry for the lack of clarity in my earlier snippet. What I meant was
#9 by dimuMurray on August 22nd, 2011 ·
And another question…why is it my code snippets aren’t nicely color-coded like yours. Using the pre tag with the lang attribute set to “actionscript3” doesn’t seem to work.
#10 by dimuMurray on August 23rd, 2011 ·
…Ignore the following. Just testing to see if I can get the color-coded snippets working…
import flash.display.DisplayObject;
#11 by Jonny Reeves on August 28th, 2011 ·
Hey Jack, any chance of an article on the performance impact of extending Proxy?
#12 by jackson on August 28th, 2011 ·
I’ll bet the performance is terrible, but it’d be good to know for sure. I’ll add the topic to my list.
Thanks for the idea. :)