Sometimes you want to pass an objects function as an argument and store that function (along its arguments) for later calling. Still you don’t want that storage to prevent its object (instance) from being destroyed (from being removed by the garbage collector). But storing a function does so, because it holds a reference to the function which belongs to an object.

It’s one of the biggest traps you can fall into when developing a larger project where many objects are created and destroyed and created and so on… geeks call that kind of thing memory leaks I think :)

So if you can avoid it: avoid it! If you can’t.. may be this little thing can help:
(more…)

I did a lot of string parsing in the recent time: CSS Selectors, XML Display Objects, Stylesheets, … I also need XML selection from String expressions – I formerly (AS2) used the great XPath4AS2 from XFactorStudio which did it’s job well (though a bit slow, it’s AS2 after all).

There’s also one for Actionscript 3 (xpath-as3). But.. well… I wanted to go for some real speed! I like XPath a lot, but we now have native E4X selection in Actionscript 3, quite a different concept of node selection, and the conversion of XPath to E4X obviously results in quite a compromise in performance.

So all I need is a decent E4X parser. And hey, I found one! E4XParser from Digital Primates. It does its job really well, especially considering the very compact code it consists of. Thanks to some preparsing and caching, it’s also quite fast.

Still I thought I can do better :-) So I planted myself for a day (and a night) in front of my displays and hacked the hell out of it. The result is a little library which does pretty much the same thing as E4XParser, though pretty much more and a little faster too (15% to 50%). It’s about half as fast as the native E4X selection (once parsed). You can do nearly anything you can do with E4X. Use it like this:

 

import com.betabong.xml.e4x.E4X;
var result : XMLList = E4X.evaluate( xmllist , "author.( name.@last == 'Jobs' )" );
 
// E4X.evaluate( source : XMLList , expression : String ) : XMLList

 
If your source is XML, just do XMLList( xml ), if your result should be xml, do xml = result[0]

Test it here

Restrictions: You can’t use AND/OR in comparisions. So, this won’t go: author.( name.@first == ‘Steve’ && name.@last == ‘Jobs’ ) – though this is only a real limitations for OR. do this for AND: author.( name.@first == ‘Steve’ ).( name.@last == ‘Jobs’ ).

What you can do: Yes, you can do quite advanced stuff like author.( name.@first == name.@last ) or car.@rating.average() (one of the few proprietary functions I added). Or even

*..car.( @brand.toLowerCase() == 'volvo' ).( parent().( localName() == 'group' ).@rating > @rating )

– a weird example, I admit, but fancy, ain’t it? :-)

This is the first time ever I’m releasing part of my library as Open Source (MIT licence). As soon as I’ll find some time (and if I see any interest), I’m gonna put this into Google Code, so everybody can easily checkout and participate. Until then download it from here:

Download (zip 13kb)

15 years ago Markus and Daniel Freitag created their first Freitag bag, made of used truck tarpaulins and some other recycled stuff. So today’s the big party, and I’ll be there of course. The party will be public starting from 11 pm @ F-abric in the Maag Areal (Zurich, of course). I sure will already be in quite a good shape at that time ;-) Give me a hoorraaaa!!

Update: Party-Pics here

In my current project I do a lot of String parsing. Much a lot! And when it comes to do the same things many many times, performance will gain much from little details.

Let’s take the simplest parsing as an example. Converting a CSS like string “width: 100%; maxwidth: 500; fontface: Bold; gap: 10;” to an object { width: “100%” , maxwidth: “500″ , fontface: “Bold” , gap: “10″ }

Compare these two methods to achieve this:

public static function simpleStringToObject_fast( input : String , o : Object = null ) : Object {
	if ( input == null || !Boolean(input) ) return o;
	if ( o == null ) o = {};
 
	var cursor : int = 0;
	var found_key : String;
	var index : int;
	while ( true ) {
 
		if ( found_key == null ) {
			index = input.indexOf( ':' , cursor );
			if ( index >= 0 ) {
				while( input.charAt(index-1) == ' ' ) index--;
				found_key = input.substring( cursor , index );
				cursor = index + 1;
				while( input.charAt(cursor) == ' ' ) cursor++;
			} else {
				break;
			}
		} else {
			index = input.indexOf( ';' , cursor );
			if ( index >= 0 ) {
				while( input.charAt(index-1) == ' ' ) index--;
				o[ found_key ] = input.substring( cursor , index );
				found_key = null;
				cursor = index + 1;
				while( input.charAt(cursor) == ' ' ) cursor++;
			} else {
				o[ found_key ] = input.substr( cursor );
				break;
			}
		}
	}
 
	return o;
}
 
public static function simpleStringToObject_slow( input : String , o : Object = null ) : Object {
	if ( input == null || !Boolean(input) ) return o;
	if ( o == null ) o = {};
 
	input = input.split(' ').join(''); // remove spaces
	var a : Array = input.split(';');
	var pair : Array;
	for ( var i:int=0 ; i 1 ) {
			o[ pair[0] ] = pair[1];
		}
	}
	return o;
}

The first one might look like some crap lacking any elegance and style, but it’s twice as fast as the second one! And hey, if you do this a million times, it can be 5 seconds instead of 10. Might not seem to be that much, but I think it’s certainly worth the extra coding :-)

(Update: I haven’t mentioned RegExp here, though it definitely deserves a mention. Thing is that Regular Expressions are just damned slow in Flash compared to String manipulations, especially with longer strings. This is kind of surprising because it’s implemented natively. But the implementation obviously isn’t too good performance wise. I hope to see improvements with F10, though haven’t read anything about it yet – and also haven’t tested yet with beta. This little article confirms my experience with RegExp: With a file of 10,000 lines, the string version is still instantaneous, but the regular expression version takes about five seconds. Even with 180,000 lines, the string version is immediate. We gave up on the regular expression version after over five minutes..)