Updated the optimized Base64 library
More than two years ago, I made a blog post about how to optimized the existing Base64 libraries.
This library was highly linked and used in multiple project as it’s 100% free (MIT license)
A few days ago I decided to take another look at it just for fun. To see if I could get it to be a bit faster.
Here is some change I made to make it even faster:
On of the biggest change was to go from bytearray.writeInt() to direct byte access bytearray[]
Optimizing the old version
//BEFORE c = data[i++] << 16 | data[i++] << 8 | data[i++]; c = (_encodeChars[c >>> 18] << 24) | (_encodeChars[c >>> 12 & 0x3f] << 16) | (_encodeChars[c >>> 6 & 0x3f] << 8 ) | _encodeChars[c & 0x3f]; out.writeInt(c); //AFTER c = data[int(i++)] << 16 | data[int(i++)] << 8 | data[int(i++)]; out[int(outPos++)] = _encodeChars[int(c >>> 18)]; out[int(outPos++)] = _encodeChars[int(c >>> 12 & 0x3f)]; out[int(outPos++)] = _encodeChars[int(c >>> 6 & 0x3f)]; out[int(outPos++)] = _encodeChars[int(c & 0x3f)];
You can also see the explicit int cast for all bytearray access. It does not always make a big difference, but depending on debug/release runtime and code, it can help a bit.
Another thing I change is the handling of “invalid” base 64 data.
When decoding a base 64 string, one of the high-cost operation was validation.
By removing validation of invalid data, it made the code 30% faster.
While I understand that validation is important in many case, having a ultra-fast library is also important for many developper.
Why not using Azoth, haXe or Alchemy SWCs
Well I could.
The problem is that right now they all use the fast-memory opcodes that won’t be supported for FlashPlayer 11.2 and upper.
This mean that any application that was build with libraries likes theses won’t be able to run in the future “as-is”
Hence, having a native-as3 library with sources that you can edit is very important.
The Result:
Grab the full source, please go and take it on this site:
http://www.sociodox.com/base64.html
and here:
/*
* Copyright (C) 2012 Jean-Philippe Auclair
* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
* Base64 library for ActionScript 3.0.
* By: Jean-Philippe Auclair : http://jpauclair.net
* Based on article: http://jpauclair.net/2010/01/09/base64-optimized-as3-lib/
* Benchmark:
* This version: encode: 260ms decode: 255ms
* Blog version: encode: 322ms decode: 694ms
* as3Crypto encode: 6728ms decode: 4098ms
*
* Encode: com.sociodox.utils.Base64 is 25.8x faster than as3Crypto Base64
* Decode: com.sociodox.utils.Base64 is 16x faster than as3Crypto Base64
*
* Optimize & Profile any Flash content with TheMiner ( http://www.sociodox.com/theminer )
*/
package com.sociodox.utils
{
import flash.utils.ByteArray;
public class Base64
{
private static const _encodeChars:Vector.<int> = InitEncoreChar();
private static const _decodeChars:Vector.<int> = InitDecodeChar();
public static function encode(data:ByteArray):String
{
var out:ByteArray = new ByteArray();
//Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed
out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms
var i:int = 0;
var r:int = data.length % 3;
var len:int = data.length - r;
var c:uint; //read (3) character AND write (4) characters
var outPos:int=0;
while (i < len)
{
//Read 3 Characters (8bit * 3 = 24 bits)
c = data[int(i++)] << 16 | data[int(i++)] << 8 | data[int(i++)];
out[int(outPos++)] = _encodeChars[int(c >>> 18)];
out[int(outPos++)] = _encodeChars[int(c >>> 12 & 0x3f)];
out[int(outPos++)] = _encodeChars[int(c >>> 6 & 0x3f)];
out[int(outPos++)] = _encodeChars[int(c & 0x3f)];
}
if (r == 1) //Need two "=" padding
{
//Read one char, write two chars, write padding
c = data[int(i)];
out[int(outPos++)] = _encodeChars[int(c >>> 2)];
out[int(outPos++)] = _encodeChars[int((c & 0x03) << 4)];
out[int(outPos++)] = 61;
out[int(outPos++)] = 61;
}
else if (r == 2) //Need one "=" padding
{
c = data[int(i++)] << 8 | data[int(i)];
out[int(outPos++)] = _encodeChars[int(c >>> 10)];
out[int(outPos++)] = _encodeChars[int(c >>> 4 & 0x3f)];
out[int(outPos++)] = _encodeChars[int((c & 0x0f) << 2)];
out[int(outPos++)] = 61;
}
return out.readUTFBytes(out.length);
}
public static function decode(str:String):ByteArray
{
var c1:int;
var c2:int;
var c3:int;
var c4:int;
var i:int = 0;
var len:int = str.length;
var byteString:ByteArray = new ByteArray();
byteString.writeUTFBytes(str);
var outPos:int = 0;
while (i < len)
{
//c1
c1 = _decodeChars[int(byteString[i++])];
if (c1 == -1) break;
//c2
c2 = _decodeChars[int(byteString[i++])];
if (c2 == -1) break;
byteString[int(outPos++)] = (c1 << 2) | ((c2 & 0x30) >> 4);
//c3
c3 = byteString[int(i++)];
if (c3 == 61)
{
byteString.length = outPos
return byteString;
}
c3 = _decodeChars[int(c3)];
if (c3 == -1) break;
byteString[int(outPos++)] = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
//c4
c4 = byteString[int(i++)];
if (c4 == 61)
{
byteString.length = outPos
return byteString;
}
c4 = _decodeChars[int(c4)];
if (c4 == -1) break;
byteString[int(outPos++)] = ((c3 & 0x03) << 6) | c4;
}
byteString.length = outPos
return byteString;
}
public static function InitEncoreChar() : Vector.<int>
{
var encodeChars:Vector.<int> = new Vector.<int>(64,true);
// We could push the number directly, but i think it's nice to see the characters (with no overhead on encode/decode)
var chars:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (var i:int = 0; i < 64; i++)
{
encodeChars[i] = chars.charCodeAt(i);
}
return encodeChars;
}
public static function InitDecodeChar():Vector.<int>
{
var decodeChars:Vector.<int> = new <int>[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
return decodeChars;
}
}
}
If you have any trick to make this faster, please post a comment!
Be an affiliate Miner!
I just wanted to let you know that TheMiner remain 100% free for all non-commercial use, but if you like the product and you want to help promote TheMiner, you can become a sale affiliate very easily!
It’s simple as:
-Put TheMiner icon on your website.. or blog.. or forum.. car painting.. cat clothes..
-Earn money if people click and buy the PRO version of this awesome software.
I want to be a sale affiliate
Got Bugs? We got the bugbase!
We just added a Mantis BugBase for TheMiner.
It’s a full anonymous access, so everyone is welcome to report TheMiner bugs to make sure they are going to be fixed quickly!
Thanks to everybody for making this such a great collaborative project!
The king is dead. Long live the king!
The king is dead:
Yes.. today I have some bad new for you. One of the best flash performance analysis tool: FlashPreloadProfiler, is officialy dead. After a LOT of time developing this profiler for flash. I decided to kill the thing.
Long live the king!
YES! After this much effort, it would be too sad to drop everything. right?
Launching today, TheMiner is the new (FLash Profiling) solution that will take the place of FlashPreloadProfiler, but with a lot of optimization, innovation and new features!
TheMiner is dedicated to every single hard-working developer that are making the most out of what they have by analysing and improving flash application. Every hardcore developer should be proud to be a miner and has such, we decided to make it look like a hero worker.
TheMiner is now part of another entity called Sociodox 
The main website as also moved to a new address: http://www.sociodox.com/theminer
PROMOTION:
TheMiner is now free for any non-commercial use
cost a little something for commercial use.
Let’s give-away a couple COUPON for TheMiner Pro
- ” IAmTheFirstMiner ” : 75% off for the first 3 ppl to buy it!
- “ 0DayCoder ” : 20% off for the first 20 ppl to buy it!
- “ HappyBugFreeChristmas ” : 12% , Everyone deserve a christmas gift!
- ” jpauclair.net ” : You love my blog? Have some percent.
- ” flashpreloadprofiler ” : For the good old time.
You are a blogger? You have a website? Talk about TheMiner or Link to it with TheMiner icons, send me the link and get 50% off!
History: from FlashPreloadProfiler to TheMiner
///////////////////////// // Added: // // One frame Trace of all methods with arguments, file and line. // DebugTexture to see stretch,smoothing, and color variation // Minimize // a QUIT button when profiler is minimed // FPS and Mem in the top bar // Screen Capture (save to file) // Pause interface in Performance & Memory profiler // Filter in Memory profiler // Filter in Function profiler // Filter in Loader profiler // Filter for file errors in loaders // Start Off (off by default) // MouseListener sprites // Usage reporting (Google Analytics) // Interlaced DataDump feature // Visual feedback in memorygraph showing GC time and weight (gray bar) // GC indicator in Flash Statistics // Auto-check update when opening configuration panel // Low process when everything off // Skin Loading / Saving // Flash Player Version in Stats tab // Added a "Already Collected" column to Memory dump // Stage Resolution in FlashStats ///////////////////////// // Fixed: // // wrong DataDump sampling recording status // bad colors for invisible object in Overdraw // bad opacity management of selection highlights // bad priority of preloader (over anything on stage) // bad instanciation for air project // Config are save automaticly when changed // Now using latest version of MonsterDebugger (v3.1) // Loader copy text not always working // Loader won't show url of stream/loader on error // MonsterDebuggerIcon needed tooltip. // multiple TheMiner classes instanciation inside reports. // multiple TheMiner self sampling in dump ///////////////////////// // Optimized: // // a LOT the main loop, now should be pretty smooth to record samples // Huge Rendering optimization in overdraw graph // Huge Rendering optimization in LifeCycle graph // Icons management // Made the bar and spacing a bit smaller
Localized:
TheMiner has also been translated by the community in 8 languages:
English, French, Russian, Dutch, Spanish, Hindi, Chinese Traditional/Simplified
These ports are inside each build.
More:
TheMiner also come with more support:
A dedicated user group, a whole website with FAQ, support, installation help and more.
14 complete tutorials on how to use most of the features
Are you a fan? Show your love!
If you were already using FlashPreloadProfiler and you liked it,
or if you now like TheMiner.
Show your love on your site or anywhere else with these icons:
![]()
Downloads:
TheMiner on Sociodox website
Session Sneak Peek #2!
The Session
Here is Second Sneak peek of our sessions “Next-generation games using Stage3D(Molehill)” (Part 1 & 2) at Adobe MAX
The videos are in HD, watch them in full res!
Flash11 Session Sneak Peak
The Session
Here is Sneak peek of my session “Next-generation games using Stage3D(Molehill)” at Adobe MAX
My friend [Jean-Philippe Doiron] and I will introduce multiple techniques such as deferred lighting, CascadeShadow Mapping, ScreenSpace Ambient occlusion, MRT, and more through vertex and fragment shaders. We will also show new ways of handling Physics, particles and pathfinding.
It’s a deep dive into GPU/CPU programming with the new Flash Player, and discover how to produce beautiful GPU effects that are reusable in your games and applications.
Please take a look at some of the things we are about to show you at the MAX!
Video Sneak Peak
The videos are in HD, watch them in full res!
Please register at AdobeMax and join the session : http://bit.ly/odwg8U
We will also do a session on Flash3D at GDC Online if you can come: http://twb.io/n5rXxy
See you all there!
Massive 3D Particle System in Flash Molehill
Evolution of Molehill
I’ve been working on Molehill for more than a year now.
Since the very first iteration, to what we have now… wow there was a huge evolution.
- Evolution (countless changes) in the API and features
- Evolution in performances
- And a lot of evolution in the community.
An old thread
can you remember the debate about PixelBender vs pure AS3 vs haxe?
Let me help you remember! There was a nice attempt by a lot of people on the net to do a massive particle system with flash.
A lot of comparison have been done between different way by the “masters”, and to honor theses efforts, I tought I’de make something with Molehill out of this old thread.
PixelBender+Alchemy option (by Ralph Hauwert)
http://www.unitzeroone.com/blog/2009/03/18/flash-10-massive-amounts-of-3d-particles-with-alchemy-source-included/
Pure AS3 option (by Joa Ebert)
http://blog.joa-ebert.com/2009/04/03/massive-amounts-of-3d-particles-without-alchemy-and-pixelbender/
haXe:
http://webr3.org/blog/haxe/flash-10-massive-amounts-of-3d-particles-with-haxe/
Revamping an old post
It’s always fun to play with particle system when using a new tech.
Today I’m presenting to you one of the very first proof of concept I made with molehill, using a technique we developed at Frima Studio. (Already one year ago!)
So I went in my archive and fixed all the API changes that were made since then.
There was also an old blog post going with it that I never released due to the “to early stage” of molehill pre-release, and the technological advantage of open-sourcing such as technique.
But since then there was a lot of development… First the presentation at Adobe Max 2010 of the ZombieTycoon trailer, Then The featured release of a couple of Zombie Tycoon levels, the session at Flash Gaming Summit 2011 and the session for the San Flashisco user group. And internally at frima, the tech never stopped to grow!
We are going to present at Adobe Max 2011. I’m sure it’s going to be awesome this year (again!).
The Particle System
This is a very simple particle system.
The particle position are defined using a classic “Strange attractor” algorithm.
Each particle is made with a quad and is facing the camera (Billboard)
Batching
THE most important thing when doing a particle system is to have a good batching process.
Particles are often in very high numbers, and they must be drawable in batch to keep the performances high enough.
When we first started thinking about it, it was pretty obvious that to create something nice with billboards, we would have to transform each quad to make it face the screen (Transform by the Inverse ViewProjMatrix). While this might sound obvious and simple to do, when processing the vertex in a vertex shader that process them one by one with no index or whatsoever defining what corners we are processing, it’s not “that” obvious!
The problem
The transformation needed on the four corners of your quad is not the same! but you can only define “one way” of doing things in your shader. (No if statement). Hence, if you can’t differentiate what you are processing, how can you make the good transformation to each vertex??
After a couple iteration where the CPU was doing the matrix transformation and re-uploaded each position each frame… We went in another direction. (It was WAY to heavy!)
The vertex shader let you define constant that you can access within the shader. Sadly, you have only 128 Float4 of theses.
So no real way of “batching” large amount of particles by making a list of transformation for each vertex. The best you could do is a couple of dynamic particle at the same time.
The trick
ZombieTycoon & Molehill Session at FlashGamingSummit
I, Speaker
This weekend I was a speaker in a conference for the very first time.
And then, monday at this one
I must say, it was damn exiting. Event more when it’s to talk about the very first game using the a technology that people has waited for years.
Adobe has even used our project as the featured game using Molehill for it’s official beta release.
The session was shared between Luc beaulieu (CTO) and me, both representing Frima Studio.
My session was about many techniques we used to create ZombieTyccon and how we managed to work with the limitations defined in Molehill.
I though it could be great to share this to everyone.
The session
download the Slides (powerpoint)
The videos
Flash Network Profiler – What are YOU downloading?
FlashPreloadProfiler RC2
Loaders Profiler
This time, it’s all about loading files.
This new profiler show you every file being loaded using
- - flash.display.Loader
- - flash.net.URLStream
- - flash.net.URLLoader
The profiling is simple, it’s going to show:
- - Current download progress
- - HTTP Status
- - File Size
- - File Url (for every display Loaders, and URLStream with IOError)
You can copy to clipboard the URL or the Errors with the left side icons.
You can also save the whole list of downloads with a “save all” option
You don’t have access to:
- - URL of display loader while it being downloaded.
- - URL of URLStream and URLLoader when download is succesful
Configs
There are now real “options” in the profiler.
You can decide to turn On and Off most of the feature so that they are not processed when you don’t need them.
You can also decide to launch the profilers you want “in the baclground” before the profiled SWF is started so that you don’t miss any information.
This new feature let you browse between tabs without loosing the data in each one.
You can also activate DeMonsterDebugger in the new Config Panel.
Project Integration
Did you have trouble with the mm.cfg file? You (like many others) were not able to use the profiler? This time is over.
There is now a SWC in the download section that you can include in your project.
The only thing you have to do is
this.stage.addChild(new FlashPreloadProfiler());
That’s it!
Video
Like the last time, I made a video of the new features:
So what’s the next step?
Until Molehill arrive officialy, I guess it’s going to be NetStream and Sockets.
FlashPreloadProfiler Project home page
If you find bugs, please submit them in the google code project, or let me know with comments here.
Have a nie and optimized day.
Complete Flash Profiler – It’s getting serious!
There was the first version, that wasn’t even looking like a profiler..
Then there was FlashPreloadProfiler Alpha and Beta..
But often I had to fallback on Flex Profiler to do the Performance Profiling.
Here is the first version that should be considered as a “fully qualified Flash AS3 profiler”.
Here is FlashPreloadProfiler RC1!
It has the basic features:
-Memory profiling
-Function Performance profiling (New!)
-Convivial UI (New!)
And it has the unique features:
-Overdraw graph
-Mouse Listeners graph
-Internal events graph
-DisplayObject Lifecycle graph
-Full Sampler recording “dump”
-Memory allocation/collection “dump” (New!)
-Function Performance “dump” (New!)
-Auto-Integration with De MonsterDebugger
-Run on debug/release SWFs
I can now officialy say that I don’t need any other tool anymore to optimize standard AS3 code. (Discussion on Molehill (Flash 3D) optimization will come soon!!)
There is a LOT of optimization that has been done in the profiler itself.
But the real new features are the new UI with ToolTips and lot’s of feedback. Plus the whole Function Performance profiling tool. There was also a lot of fixes in the code.
Here is the PerformanceMonitor screen:

This time, I’ve also made a full video of me explaining what the tool is all about and how to use it!
The video quality is very bad and I’m going to upload a better version really soon. Sorry!
Again, comments are very very welcome! You can post them on the google code project or right here on my blog.
If you want to participate, please send me a mail!
If you want to contribute financialy, there is a link on the profiler page and on the google code page.
Funny fact:
While developping the profiler, I ran Flash CS5 without removing the profiler first…
And I knew that FlashIDE was running SWF inside the main interface.. But to see that one of the main components was using some GrantSkinner library, that was just plain hillarious! Go check it out!
Reference:
FlashPreloadProfiler project
