Friday, March 13, 2009

Alchemy Data Manipulation Faster Than Vectors

While working with Alchemy to port a roguelike library to handle field of view calculations for a 2d tile game (The Doryen Library, port is called libtcod-alchemy) I noticed some drastic speed differences between using a ByteArray in pure AS and manipulating that same ByteArray inside Alchemy. Out of curiosity I wondered how Alchemy manipulations of large data structures would compare to a native AS Array or the new (and faster) Vector.

As it turns out, Alchemy wins hands down when the data is already in a ByteArray. If you need to transfer data from an array/vector into a ByteArray to hand off to Alchemy and then transfer it back, it is slower to use Alchemy. For this test I have a collection of 1,000,000 numbers and for each iteration of the test, I loop over the numbers and add one.

Alchemy ByteArray additions are about 6 times faster than Vector integer additions and 10 times faster than pure AS manipulations of a ByteArray (when using Array notation [] on a ByteArray to manipulate a Byte - using position, readInt() and writeInt() in AS is much slower).

Below is test program that proves it:

Note that the demo above requires Flash Player 10 (required by Alchemy).

NOTE: If you want view the source, you need to go here and right click on the app (the embedded version in blogger doesn't know where to look for the source).

This tells me a few things:
  • There is a great deal of room for improvement in ActionScript's compiler since it should perform better IMHO. I understand some slow downs due to type safety, garbage collection, etc but I didn't expect the huge difference.
  • If Alchemy had native access to the same Native calls used to seralize data to AMF that is used in AS (described here), Alchemy would be blazingly fast for manipulating data even when stored in Arrays or Vectors. You would just serialize the objects as AMF into Alchemy, manipulate the data with Alchemy, and serialize it back out as AMF back to AS.
  • The ByteArray.position is much slower than I would expect.
  • If you need to process large amounts of data, seriously consider using Alchemy. Remember the marshalling tax to and from Alchemy - every bit of data passing into and out of Alchemy takes time to marshall, so you want to do it in large chunks like in my speed test.
You may notice that the first Alchemy test takes more time than normal - this is due to initialization of the Alchemy library.

In case you are curious essentially the same test takes:
  • GCC C Code - 1 or 2 milliseconds
  • GCC Lua Code - 300-400 milliseconds
  • Lua Alchemy - 8 seconds (might be including some of the time to get the tick count from ActionScript)

Sunday, February 1, 2009

Lua Alchemy Getting Sweeter in v02a

Thanks to Alexander Lua Alchemy now has sugar! What this means is you no longer need to make calls like the following in the Lua Alchemy code:
as3.call(myvar, "someCall", param1, param2)

Instead you can make calls that look like native Lua code:
myvar.someCall(param1, param2)

This includes chaining calls like a.b.c().d

Below is a preview of the release:

Note that the demo above requires Flash Player 10 (required by Alchemy and my use of the local file system to allow opening/saving files). It is also hosted here where it can take up a full browser screen and is much easier to read.

You will notice in the demo code a great number of calls to as3.tolua(xxx). These calls convert ActionScript types into Lua types where possible. We removed all automatic conversion from AS3 to Lua types for performance reasons - each time you cross the Lua<->C<->AS3 boundary you have to pay the Alchemy wrapper performance tax.

For more information on the upcoming release of v0.2a (official downloads available in the next few days) see: