Ralph Hauwert put a very interesting blog post up no his blog about Adobe Alchemy. Basically he was reading my mind with this post.
I want to a step further now. But please keep in mind that I am definitly not a compiler expert or have deep knowledge of the Flash Player. Everything I write about is in my opinion common sense and comes from a long time of reverse engineering and autodidactic learning.
Alchemy
First of all I have to say that Alchemy is a great research project and I have full respect for Scott Peterson and his work. He did an awesome job and I am more than happy that Alchemy has now been released on labs because people begin to question now the Flash Player, ActionScript and the ASC (ActionScript Compiler).
So why is Alchemy faster than using plain ActionScript — or is that true at all? I do not want to disappoint anyone here but writing C/C++ code instead of ActionScript is not the right way. Alchemy will never be faster than your plain handoptimized ActionScript and it still has to prove for me that it is actually faster. All my comparisons between Alchemy and ActionScript showed that using ActionScript is in most cases faster.
But it makes sense to use Alchemy. An audio encoder for instance runs for a long time on its own without having to exchange data. Currently it is very slow to transfer data between Alchemy and ActionScript on every frame. This does not mean Alchemy is bad, but it will not work for your fast inverse square root algorithm.
So why can Alchemy be faster at all? There are a couple of reasons for that.
- C/C++ can be compiled and optimized much better than ActionScript
- The language offers you features you would dream about as an ActionScript programmer (operator overloading, method inlining, templates, etc.)
- The LLVM does a really good job on optimizing its intermediate language
- Alchemy comes with some new opcodes for the Flash Player that allow very fast ByteArray operations
- Alchemy uses a modified ASC that supports inlining of Flash Player bytecodes.
So just to make one thing cristal clear: If the new opcodes would not exist, Alchemy would produce very poor results in terms of execution speed. But albeit that I have to disappoint you about the execution speed of Alchemy in general. Nicolas Cannasse wrote an interesting blog post about this issue and I completely agree. ActionScript does not support a lot of features which C/C++ offers — pointers for instance. All those features have to be wrapped and this means a significant speed loss.
But I do not want to start an Alchemy bashing here. I still think it is a really great technology and the main use case is not fast code execution. But it brings me to my next points: The ActionScript language and the ASC.
ActionScript
ActionScript has been designed several years ago and Adobe had always the incentive to be ECMA compilant. Being standards compilant reduces a certain level of innovation and recuded the power of the Flash Player in the last years. Right now, ActionScript 3 is not an ECMA compilant language. And I am not saying this because ECMA Script 4 has been dropped. ActionScript 3 added additional “features” even before that happened.
For a long time ActionScript 3 has been very close in terms of its ECMA compilance but I think it is now time for innovation. The ActionScript 3 language does not fulfill most of the professional needs.
Have you ever looked at haXe? I hope you did. haXe is definitly not perfect but I want give you a small excerpt of haXe language features which will make your mouth water:
- You are able to use type parameters
- You are able to use function types like
Event -> Voidfor an event listener instead ofFunction - Enums instead of the
public static constconvulsion
Why am I talking about haXe at all? Java has most of those features implemented as well and several other languages too. But haXe can output a SWF so we can compare it to ActionScript. haXe is in a lot of ways superior to ActionScript and I did not talk about the compiler yet.
The quintessence is that ActionScript is not a feature rich language compared to mature ones. And even a single French genius can develop something better than a multi-million dollar company. What the hell is going on here?
The main problem of ActionScript is that you lose most of your types along the way and therefore the compiler can not produce a good output. E.g. everytime you put some object into an Array in ActionScript its type is lost unless you cast of course when reading again — and I hope you do that. This is a really big problem. This is the reason why Alchemy can produce “better ActionScript” than you. Not because you are stupid but because you do not have the tools in ActionScript to do that. And this is a shame for Adobe. So many great developers could produce such a great output but they are not allowed to.
ActionScript Compiler
One of the main problem in the whole Flash universe is the ActionScript compiler. This is a little bit harder to explain because it is a little bit more abstract. Some problems exist because of the ActionScript language nature. But some problems exist because of the compiler itself. Let me explain this with an example:
package {
public final class Example extends flash.display.Sprite {
public function Example() {
var a: int = 1+2;
var b: int = a;
var c: int = b+1;
}
}
}
This code will produce exactly this output for the constructor:
get_local0
pushscope
get_local0
constructsuper 0
pushbyte 1
pushbyte 2
add
convert_i
set_local1
get_local1
convert_i
set_local2
get_local2
pushbyte 1
add
convert_i
set_local3
returnvoid
The interesting part has been marked bold. Let me explain what is going on here:
- Put value 1 on the stack
- Put value 2 on the stack
- Add the two values which are on the stack together using floating point calculus
- Convert this floating point value to an integer
- Set this value to local register one which is
a - Put the value of local register one on the stack
- Convert this floating point value to an integer
- Set the value to local register two which is
b - Put the value of local register two on the stack
- Put value 1 on the stack
- Add the two values which are on the stack together using floating point calculus
- Convert this floating point value to an integer
- Set this value to local register three which is
c
Basically this is an example for the worst output a compiler could produce. First of all b is not needed at all in our code. We hold just the value a in b. a holds a constant value 3. Why do we have to add this stuff together at runtime everytime if it is constant? For c we add the constant value 1 to the constant value 3 which has been stored in a. The compiler should know at this point three things: a is constant, b is not needed, c is constant. The compiler could just set c to the integer value of 4. This is also what I would expect for a SmallWebFormat.
But to make it even more interesting: c is not used at all. So why does the constructor contain any bytecode at all besides calling the super constructor? And to make it a little bit more absurd: Try doing the same in PixelBender and use Tinic’s disassembler. You will see that you will not find any of your local variables in the PixelBender bytecode — which is correct. And the answer why the PixelBender compiler is smarter than the ASC is quite easy: Adobe uses the LLVM for PixelBender as well. Remember the LLVM is what Alchemy is using. This means basically that PixelBender has a better compiler than we have for ActionScript. This is sad and insane but true.
With the haXe compiler you will get nearly the same output as the ASC with certain differences. All the variables are integer values and therefore haXe uses integer calculus. And the last addition does not involve b at all. haXe will not ignore that a, b and c are not used at all. But as I said: haXe is definitly not perfect — but it is by far better.
I have asked for certain features a lot in the past and implemented them for myself. I asked Adobe to support the __asm keyword even before Alchemy and they refused it. Of course I am a little bit disappointed about that because now they use it for Alchemy and they see it makes sense. Basically having a __asm keyword allows you to get around the nonsense which the ASC produces at least for performance critical loops. This is why I started writing AS3C but it is basically a stupid idea to try optimizing on a byte code level but it integrated very well into my daily workflow.
The Flash Player could work much faster if we could access certain things with ActionScript. The lookup of a class can be stored in a local variable for instance which gives a significat speed boost. haXe already allows you to do that via var m = Math. Why do we have to wait for such things so long?
Thoughts
Now after writing about Alchemy, ActionScript and the ASC I think that you get the idea. What we need is a compiler that works. And once the new Alchemy opcodes are supported in the ASC it will be much more fun to write your lightning fast ActionScript code instead of converting C libraries. We need a mature language which allows us to work in professional large-scale environments and which allows the compiler to produce a good output.
Libraries which are a community-darling could become even better, easier to use and faster in execution speed which would result in better user experiences.
I would like to see a faster and more innovative development of ActionScript and the ASC. But then there are the politics and all the bussiness stuff so we will have to wait probably for ages until we get what we need. Right now we can use alternatives such as haXe. And the good thing is that other companies do not sleep as well. I would love to write C# instead of ActionScript but Silverlight just sucks. Maybe someone could write a C#->LLVM->ActionScript->SWF compiler toolkit?
20 Comments
Interesting article. I was completely ignorant of the quality of the output that the Flash compiler spits out thinking it was a good as it could get. Now I know otherwise. Perhaps Adobe could provide an update in the future for Flash/Flex so that they use the LLVM to produce improved output…
Here’s an idea : why don’t we build an ActionScript -> ABC compiler with LLVM ? ;-)
“I would love to write C# instead of ActionScript but Silverlight just sucks.” thumbs up! I’ve dreamed for C#->SWF compiler as well.
Although AS3 is fun to use language it need a lot of speed and OOP features boost. Especially the lack of typed containers and templates has been killing me…
As I think of it flash developers should have been able to write code that renders quake quality real time 3d since AS3 was introduced but I haven’t seen it yet.
Can’t adobe copy some of the niceties from C# into AS3?
I’d rather see a Ruby -> SWF compiler ;)
I’ve seconded the request for __asm in the ActionScript compiler on the Alchemy forums. No response. http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=72&catid=755&threadid=1407686&enterthread=y
I created a front-end script for Alchemy’s ActionScript compiler to use for general AS work and it seems functional. However without exhaustive testing I can’t say whether it is a 100% superset of the standadard ActionScript compiler.
Very, very, very interesting Joa. Thanks for sharing your knowledge :) I’ll have to try haXe at some point…
great article! hope adobe will consider your statements and give us an optimized compiler soon.
the Adobe official paper said that every object created will be stored in the memory no matter you use it or not.At this point adobe means that you should optimize your code BY YOURSELF.so the performance of ASC is REASONABLE?=.=
w/e,wish to get some mechanism allowing developer to write low-level code to improve the performance of as3.
I do not really get your point. I mean let’s face it. The key is that we want to write nice readable OOP code which is still performant. And if I write this
public function get x(): Number { return _x; }a compiler or the runtime has to be smart enough to inline this call instead of calling a method.Unfortunately I still have my problems with the VM and it behaves like a blackbox. Adobe says that constant folding is for instance not applied by the compiler but by the VM. Then I wonder why a public static const still sucks so much performance.
Adobe says they have early binding in the VM but static method calls are much more expensive than instance calls. From my understanding they should be equal with early binding.
So if I can not trust the VM I have to trust the compiler because the compiler output (ABC) is what I can look at very easy. Of course Tamarin has been opensourced so you can also take a look at the
codegenfolder but that is much more complicated than writing your own dasm.Hi Joa,
You’re right to complain about ASC code output, since it is not very good. But keep in mind that some optimizations such as constant expression propagation and dead code elimination are performed at runtime by the AVM2 JIT, since the SSA representation is much more easy to optimize than the AVM2 bytecode.
You are right but as I said the AVM2 JIT is doing more than the compiler. The only problem is verifying what the JIT is doing.
I do not know if you have made your own experiences. But in the comment above I said that I do not understand a lot of stuff the AVM2 is doing or why it behaves slow in some ways (static vs. instance).
I think it would be pretty nice to have a CIL => ABC converter, so we can convert any .NET binary to a SWF. Because the CLS is much closer to AS3 than C/C++, this converter would have to put less additionnal code in the swf to have an equivalent SWF binary. It would not be perfect as is (for example, the binaries are not inlined, since the inlining work is done by the .NET jitter) but I guess someone doing such compiler could add some compiler magic.
Also, I was looking at this new memory access bytecode stuff, and saw that they were actually available through a ByteArray exposed by ApplicationDomain.domainMemory. Well, that’s what the documentation says and I did not take the time to benchmark it or look at the generated IL when it’s used(do you have any good IL reader tool to advice btw ?). It would be interesting to compare this ByteArray access times against Haxe’s Memory class ones.
Anyway, I’ll definitely look into doing that CIL-SWF converter..
There is already a CIL->ABC converter at http://jsc.sourceforge.net/ but I did not take a look at it yet.
By the way you can still use AS3C as a free dasm. But it does not work with haXe generated SWF files.
my jsc compiler will let you write your flash application in c# and compile it to actionscript source code. Then you would need to use flex compiler to get the actual swf file.
:) try it
I have strong background in C, and Java, Actionscript. Therefore, I can’t be agree with the points you make. You asked: “So why is Alchemy faster than using plain ActionScript — or is that true at all? ” It is faster because you can organize and manage your memory by yourself, as a result, you can implement better algorithms and you can obtain better performance. These are known facts among C programmers. There are many open source projects implemented in C/C++. Actionscript developers will be able to access these codes. Alchemy rocks!!!
But you do understand that the C code is compiled to ABC which runs in the AVM2 and therefore all your unmanaged memory cocd has to be wrapped to work in a virtual machine with managed memory.
I wonder how you want to explain to me now why this should be faster?!
The answer is clear: check the following link, and play doom in your browser and see the performance:
http://www.peterelst.com/blog/2008/12/18/porting-doom-to-flash-interview-with-mike-welsh/
Please read the post before making any comments. It seems like you did not understand at all what I am talking about.
Posting examples makes no sense and I will not answer to this any longer. If I say that the Alternativa bunker demo is running in fullscreen with way much higher quality it makes also no sense because that is not the whole point of this post. Sorry.
you wrote: “Basically Ralph Hauwert was reading my mind with this post.” Joa, you should check Ralph Hauwert’s new post : http://www.unitzeroone.com/blog/2009/03/18/flash-10-massive-amounts-of-3d-particles-with-alchemy-source-included/
sincerely,
This is a very interesting blog and so i like to visit your blog again and again. Keep it up.
Sharon
http://www.bukisa.com/articles/274655_how-to-become-a-better-listener
3 Trackbacks
[...] > Alchemy, ActionScript and the ASC at blog.joa-ebert.com – Blog of Joa Ebert [...]
[...] 在Joa Ebert的BLOG上面找到這篇文章,還有裡面鏈結到的另一篇文章 [...]
[...] Lack of flexibility a big problem with Scholarship RESP Plans | Canadian CapitalistGrowing Business With Online Marketing Ideas | Optimise My WebsiteIs John McCain insane? How to make money with mobile squeeze pagesAlchemy, ActionScript and the ASC [...]