Skip to content
January 12, 2012

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!

January 12, 2012

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

 

December 15, 2011

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!

 

TheMiner BugBase

TheMiner Home Page

December 12, 2011

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.

You ARE TheMiner(s)

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

  1. ” IAmTheFirstMiner ” : 75% off for the first 3 ppl to buy it!
  2. “ 0DayCoder ” : 20% off for the first 20 ppl to buy it!
  3. “ HappyBugFreeChristmas ” : 12% , Everyone deserve a christmas gift!
  4. ” jpauclair.net ” : You love my blog? Have some percent.
  5. ” 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

October 3, 2011

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

Here is the first sneak peek

The videos are in HD, watch them in full res!

September 27, 2011

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!

July 18, 2011

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.
I have never seen such a great group of people working at the same time on a pre-release, in all possible application of the tech.
Still! When I look at the demos out there today, there is not much!
You can take a look at “The big list” by Lee Brimelow

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

Read more…

March 1, 2011

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

Read more…

January 25, 2011

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.

 

December 23, 2010

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

Follow

Get every new post delivered to your Inbox.

Join 399 other followers