<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Andy Li’s Blog - JavaScript</title><link href="https://blog.onthewings.net/" rel="alternate"></link><link href="http://feeds.feedburner.com/tag/javascript/feed/atom.xml" rel="self"></link><id>https://blog.onthewings.net/</id><updated>2010-08-03T23:41:00+08:00</updated><entry><title>Using jQuery in haXe</title><link href="https://blog.onthewings.net/2010/08/03/using-jquery-in-haxe/" rel="alternate"></link><published>2010-08-03T23:41:00+08:00</published><updated>2010-08-03T23:41:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2010-08-03:/2010/08/03/using-jquery-in-haxe/</id><summary type="html">&lt;p&gt;It is a kind of pain to code in &lt;span class="caps"&gt;JS&lt;/span&gt; without a proper library like
&lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. Using plain haXe in &lt;span class="caps"&gt;JS&lt;/span&gt; target is just as pain since haXe
does not abstract most of the browser quirks, what it gives is
only stricter typing and a little bit better core &lt;span class="caps"&gt;API …&lt;/span&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;It is a kind of pain to code in &lt;span class="caps"&gt;JS&lt;/span&gt; without a proper library like
&lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. Using plain haXe in &lt;span class="caps"&gt;JS&lt;/span&gt; target is just as pain since haXe
does not abstract most of the browser quirks, what it gives is
only stricter typing and a little bit better core &lt;span class="caps"&gt;API&lt;/span&gt; (nothing &lt;span class="caps"&gt;DOM&lt;/span&gt;
related…). When there is no solid haXe/&lt;span class="caps"&gt;JS&lt;/span&gt; targeted haxe library come
out yet, we have to find some ways to use external &lt;span class="caps"&gt;JS&lt;/span&gt; libraries.&lt;/p&gt;
&lt;p&gt;There is a &lt;a href="http://lib.haxe.org/p/jquery"&gt;jQuery wrapper&lt;/a&gt; appeared on haxelib last year, but I don’t
really like its &lt;span class="caps"&gt;API&lt;/span&gt;, which is too different from the original one, and
I’ve never used to having method names first letter capitalized… &lt;span class="caps"&gt;OK&lt;/span&gt;,
it’s just personal taste :P Anyway I’ve written a &lt;a href="http://lib.haxe.org/p/jQueryExtern"&gt;jQuery extern&lt;/a&gt; to
replace it, which provides &lt;span class="caps"&gt;API&lt;/span&gt; closer to jQuery and smaller compiled &lt;span class="caps"&gt;JS&lt;/span&gt;
file (smaller because the haXe compiler does not generate codes for
extern class).&lt;/p&gt;
&lt;p&gt;Here I will illustrate a bit on how to use it, requiring you to have
some experience on both haXe and jQuery.&lt;/p&gt;
&lt;h3&gt;Installing the jQuery extern&lt;/h3&gt;
&lt;p&gt;Since its put on haxelib, you can install it using the command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;haxelib install jQueryExtern
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and then add &lt;code&gt;-lib jQueryExtern&lt;/code&gt; in the hxml.&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;OR&lt;/span&gt;, you can download the cutting edge version from Github:
&lt;a href="http://github.com/andyli/jQueryExternForHaxe"&gt;http://github.com/andyli/jQueryExternForHaxe&lt;/a&gt;, extract and place
“JQuery.hx” (optionally with the “jQueryPlugins” folder) into your
project source directory.&lt;/p&gt;
&lt;h3&gt;Using the jQuery classes&lt;/h3&gt;
&lt;p&gt;It should be better to illustrate with example. For a typical &lt;span class="caps"&gt;JS&lt;/span&gt;
starting point with jQuery, you write:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;//do your magic&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don’t know, it’s a short-hand that bind your magic codes to the
document ready event, same as you write:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;//do your magic&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;HaXe does not allow using &lt;code&gt;$&lt;/code&gt; as a class name or a function name, but
&lt;code&gt;$&lt;/code&gt; is just a short-hand to &lt;code&gt;jQuery&lt;/code&gt;. However, haXe requires all class
names start with capital letter, so it is &lt;code&gt;JQuery&lt;/code&gt; not &lt;code&gt;jQuery&lt;/code&gt;. You
start your haXe/&lt;span class="caps"&gt;JS&lt;/span&gt; codes using the jQuery extern as following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;JQuery&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="n"&gt;Void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="n"&gt;Void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//your magic codes&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It seems to be a few lines more than &lt;span class="caps"&gt;JS&lt;/span&gt;, but you should already know,
the extra lines are the same for all other haXe targets, its how haXe
program starts. The main point is &lt;code&gt;new JQuery(...)&lt;/code&gt; which is the same as
&lt;code&gt;$(...)&lt;/code&gt; in &lt;span class="caps"&gt;JS&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;So, when you code in &lt;span class="caps"&gt;JS&lt;/span&gt; like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"#myMightyDiv"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;now you do the same in haXe:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"#myMightyDiv"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Simple.&lt;/p&gt;
&lt;h3&gt;Static functions&lt;/h3&gt;
&lt;p&gt;One thing to aware, that is the static methods of jQuery are placed to
&lt;code&gt;JQueryS&lt;/code&gt; in the extern. The reason is haXe does not allow using same
name for both static and instance methods. For example in the original
jQuery, there is &lt;code&gt;$.data()&lt;/code&gt; and &lt;code&gt;$(...).data()&lt;/code&gt;, they are now in the
extern as &lt;code&gt;JQueryS.data()&lt;/code&gt; and &lt;code&gt;new JQuery(...).data()&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Extra methods in the jQuery extern&lt;/h3&gt;
&lt;p&gt;And there are some extra methods appears in the extern comparing to the
original jQuery. For example, there is &lt;code&gt;cssSet()&lt;/code&gt;, and it is just the
same as &lt;code&gt;css()&lt;/code&gt; but limiting you to really setting a &lt;span class="caps"&gt;CSS&lt;/span&gt; property and it
is properly typed as returning a JQuery object, so you can happily
chaining the methods with code completion and type checking. All the
extra methods are like that and they are all set as &lt;code&gt;inline&lt;/code&gt;, so that
the haXe compiler will generate correct codes, that is &lt;code&gt;css()&lt;/code&gt; not
&lt;code&gt;cssSet()&lt;/code&gt; in the compiled &lt;span class="caps"&gt;JS&lt;/span&gt;, because &lt;code&gt;cssSet()&lt;/code&gt; is not really existing
in jQuery. And because they are not really existing, don’t try to call
the extra methods with Reflect.&lt;/p&gt;
&lt;h3&gt;Using plug-ins&lt;/h3&gt;
&lt;p&gt;I’ve included some jQuery plug-in externs. Currently there are &lt;a href="http://flowplayer.org/tools/"&gt;jQuery
Tools&lt;/a&gt;, &lt;a href="http://jquery.malsup.com/media/"&gt;jQuery media plug-in&lt;/a&gt; and &lt;a href="http://jqueryui.com/"&gt;jQuery &lt;span class="caps"&gt;UI&lt;/span&gt;&lt;/a&gt; (work-in-progress).&lt;/p&gt;
&lt;p&gt;The plug-in architecture is a bit hard to deal with… To understand how
it works, first of all you have to know there is a mighty “&lt;a href="http://scwn.net/2009/05/23/injecting-methods-into-haxe-classes-with-using/"&gt;using&lt;/a&gt;”
keyword in haXe, which inject methods into object instance. And the
jQuery plug-in in my haXe extern is utilizing both “using” and “inline”.&lt;/p&gt;
&lt;p&gt;Anyway, here is how you use the plug-ins. For example, when using
&lt;a href="http://flowplayer.org/tools/"&gt;jQuery Tools&lt;/a&gt; in &lt;span class="caps"&gt;JS&lt;/span&gt;, you just include its &lt;span class="caps"&gt;JS&lt;/span&gt; file in &lt;span class="caps"&gt;HTML&lt;/span&gt; and you can
call the plug-in’s method on the jQuery object, that is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".my_overlay_trigger"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;({...});&lt;/span&gt; &lt;span class="c1"&gt;//overlay is from jQuery Tools&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In haXe, with my extern, you have to write:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;JQuery&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//there are several classes in Overlay.hx, we "using" only the "Overlay" class.&lt;/span&gt;
&lt;span class="kn"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;jQueryPlugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;jQueryTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Overlay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".my_overlay_trigger"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because this implementation doesn’t deal with optional parameter very
well, in most of the cases I made the optional parameters mandatory. If
the method has a optional config parameter, but you just want to use the
defaults, simply pass in &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And there are many cases some functions does not fit that well, I’ve
wrap them into classes/methods with &lt;code&gt;inline&lt;/code&gt;. You may have to look at
the source file to fully understand how to use.&lt;/p&gt;
&lt;p&gt;There will be more plug-ins to come when I need them. Feel free to
integrate other plug-ins and let me put them into the extern.&lt;/p&gt;</content><category term="Haxe"></category><category term="JavaScript"></category><category term="jQuery"></category></entry><entry><title>CanvasBlock: a GM script to block canvas tag (should we…or can we?)</title><link href="https://blog.onthewings.net/2010/04/13/canvasblock-a-gm-script-to-block-canvas-tag-should-we-or-can-we/" rel="alternate"></link><published>2010-04-13T02:41:00+08:00</published><updated>2010-04-13T02:41:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2010-04-13:/2010/04/13/canvasblock-a-gm-script-to-block-canvas-tag-should-we-or-can-we/</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;HTML5&lt;/span&gt; is believed to be the Flash killer and will replace Flash in the
future. Eventually those Flash-haters will become canvas-haters, so a
canvas-blocking GreaseMonkey script will be useful (at least they think
it will be).&lt;/p&gt;
&lt;p&gt;I myself was making it for fun. I don’t think we should block …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;span class="caps"&gt;HTML5&lt;/span&gt; is believed to be the Flash killer and will replace Flash in the
future. Eventually those Flash-haters will become canvas-haters, so a
canvas-blocking GreaseMonkey script will be useful (at least they think
it will be).&lt;/p&gt;
&lt;p&gt;I myself was making it for fun. I don’t think we should block any &lt;span class="caps"&gt;HTML5&lt;/span&gt;
tags anytime since it is a part of the web, just like I do not agree
people blocking Flash. What is interesting is, seems like we
cannot effectively block the canvas tag, which will be discussed later
in this post.&lt;/p&gt;
&lt;h3&gt;Features&lt;/h3&gt;
&lt;p&gt;I made the script blocks not only canvas tag but also video tag and
audio tag. It is because Flash is going to be replaced by all the three
tags but not only canvas. Video and audio can be as annoying as canvas.&lt;/p&gt;
&lt;p&gt;Like those Flash-blockers, the blocked contents are replaced by a line
of text, “Click to show xxxx”. You may click on it to get back the
blocked content.&lt;/p&gt;
&lt;p&gt;CanvasBlock is tested on Firefox 3.6 on Mac, Firefox 3.5 on Ubuntu and
Chrome on Ubuntu. Other platforms should works too.&lt;/p&gt;
&lt;h3&gt;Implementing the script&lt;/h3&gt;
&lt;p&gt;I used haXe instead of writing pure &lt;span class="caps"&gt;JS&lt;/span&gt;. No big reason here, just to see
if it is possible. Turn out there is no big difference from using &lt;span class="caps"&gt;JS&lt;/span&gt;,
you just need to copy all the meta data to the compiled &lt;span class="caps"&gt;JS&lt;/span&gt; file. And the
events listener need to be assigned by &lt;code&gt;addEventListener&lt;/code&gt; instead of
something like &lt;code&gt;onclick = function ...&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Detecting &lt;span class="caps"&gt;HTML5&lt;/span&gt; tags is easier than detecting Flash objects. Firstly,
the tags are standardized meaning you can simply use
&lt;code&gt;getElementsByTagName&lt;/code&gt;. For Flash objects you need to check the params
of the &lt;code&gt;object&lt;/code&gt; and the &lt;code&gt;embed&lt;/code&gt; tags, which is a bit troublesome.
Secondly, currently no one (at least not much ppl) is creating canvas
tags on the fly, unlike for Flash the standard way is to use swfobject.
So I can detect the tags once the &lt;span class="caps"&gt;DOM&lt;/span&gt; is ready, no need to wait for the
execution of the page’s &lt;span class="caps"&gt;JS&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Replacing the tags and saving them for later retrieval is easy too.
Using normal &lt;span class="caps"&gt;JS&lt;/span&gt; method will work.&lt;/p&gt;
&lt;h3&gt;The tags are blocked but…&lt;/h3&gt;
&lt;p&gt;The script is functional and I went to do some more testing. Blocking
video and audio seems ok, but there is some problem of blocking canvas.&lt;/p&gt;
&lt;h4&gt;Possibility of Freezing/Crashing&lt;/h4&gt;
&lt;p&gt;I went to &lt;a href="http://www.chromeexperiments.com/"&gt;ChromeExperiments&lt;/a&gt; and randomly picked &lt;a href="http://www.chromeexperiments.com/detail/asteroids-game/"&gt;one&lt;/a&gt;. You know
what? The browser froze.&lt;/p&gt;
&lt;p&gt;So, look like after I blocked the canvas, the &lt;span class="caps"&gt;JS&lt;/span&gt; on the page which is
used to draw thing on the canvas originally, is still there trying to
work on the canvas. And this become a big problem since I don’t
know exactly which &lt;span class="caps"&gt;JS&lt;/span&gt; function is going to work on
canvas, because different web page have different functions, so no way I
can work on that. You can completely disable &lt;span class="caps"&gt;JS&lt;/span&gt;, but this is not a
CanvasBlock should do.&lt;/p&gt;
&lt;p&gt;Browser froze and an timeout message was shown after blocking canvas:
&lt;img alt="Browser freezed and an timeout message was shown after blocking canvas" src="/files/2010/errorAfterBlockingCanvas.png"/&gt;&lt;/p&gt;
&lt;p&gt;However, I have tested some more web page and they are ok with the
blocking script. So maybe only some complex &lt;span class="caps"&gt;JS&lt;/span&gt; will have this problem.
But anyway the possibility of freezing a browser is not a good thing.&lt;/p&gt;
&lt;h4&gt;No significant reduction on &lt;span class="caps"&gt;CPU&lt;/span&gt; usage&lt;/h4&gt;
&lt;p&gt;The remaining &lt;span class="caps"&gt;JS&lt;/span&gt; script  problem reminded me to test on the &lt;span class="caps"&gt;CPU&lt;/span&gt; usage.
And the result is, blocking canvas does not bring significant reduction
on &lt;span class="caps"&gt;CPU&lt;/span&gt; usage. See the following screenshots, which is using &lt;a href="http://www.chromeexperiments.com/detail/aquarium/"&gt;another
Chrome experiment&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Page opened, canvas blocked. However &lt;span class="caps"&gt;CPU&lt;/span&gt; usage still rise to a
very high level:
&lt;img alt="Page opened, canvas blocked. However CPU usage still rise to a
very high level." src="/files/2010/cpuUsage-1.png"/&gt;&lt;/p&gt;
&lt;p&gt;Clicked to show back the canvas. &lt;span class="caps"&gt;CPU&lt;/span&gt; usage rose even higher,
but not much difference:
&lt;img alt="Clicked to show back the canvas. CPU usage rose even higher,
but not much difference." src="/files/2010/cpuUsage-2.png"/&gt;&lt;/p&gt;
&lt;p&gt;So what’s that mean? Again if I want to block the real &lt;span class="caps"&gt;CPU&lt;/span&gt; hog, I should
block the &lt;span class="caps"&gt;JS&lt;/span&gt; with the canvas. But again, stated above, it is not
possible to block the right function without blocking all &lt;span class="caps"&gt;JS&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Blocking canvas can only introduce little benefit on &lt;span class="caps"&gt;CPU&lt;/span&gt; usage but give
you possibility of freezing/crashing!&lt;/p&gt;
&lt;p&gt;Let’s look at Flash again. Flash can be blocked easily because
ActionScript is included in the swf. Removing the swf from the
page automatically removes the associated scripts. Also, usually &lt;span class="caps"&gt;JS&lt;/span&gt; does
not control a Flash object so it is pretty safe to kick Flash out
without dealing with the remained &lt;span class="caps"&gt;JS&lt;/span&gt;. From this point of view, seems
that Flash is more user friendly than canvas, and &lt;span class="caps"&gt;HTML5&lt;/span&gt; ads will be more
annoying than Flash ads…&lt;/p&gt;
&lt;p&gt;If you want to try, you may install the script from &lt;a href="http://userscripts.org/scripts/show/74216"&gt;CanvasBlock’s page
on userscripts.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You’re also welcome to get the haXe source from &lt;a href="http://github.com/andyli/CanvasBlock"&gt;CanvasBlock’s Github
repo&lt;/a&gt;.&lt;/p&gt;</content><category term="Flash"></category><category term="Haxe"></category><category term="HTML5"></category><category term="JavaScript"></category></entry><entry><title>AS3/JS string concatenation methods performance test</title><link href="https://blog.onthewings.net/2009/10/09/as3-js-string-concatenation-methods-performace-test/" rel="alternate"></link><published>2009-10-09T23:25:00+08:00</published><updated>2009-10-09T23:25:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-10-09:/2009/10/09/as3-js-string-concatenation-methods-performace-test/</id><summary type="html">&lt;p&gt;When writing &lt;a href="https://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/"&gt;BrainFlash&lt;/a&gt;, I was thinking if the string concatenations
for program output will slow down the whole interpreter. That is because
I was once hit that a year ago when dealing with &lt;span class="caps"&gt;XML&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I asked for better handling methods over &lt;a href="http://stackoverflow.com/questions/1536260/string-concatenation-is-extremly-slow-when-input-is-large"&gt;StackOverflow&lt;/a&gt;. It is
interesting that some of the answers …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When writing &lt;a href="https://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/"&gt;BrainFlash&lt;/a&gt;, I was thinking if the string concatenations
for program output will slow down the whole interpreter. That is because
I was once hit that a year ago when dealing with &lt;span class="caps"&gt;XML&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I asked for better handling methods over &lt;a href="http://stackoverflow.com/questions/1536260/string-concatenation-is-extremly-slow-when-input-is-large"&gt;StackOverflow&lt;/a&gt;. It is
interesting that some of the answers shown that using “+=” is already
the fastest. But I still want to know more about that, so I wrote my own
simple testing program, which is below:&lt;/p&gt;
&lt;h3&gt;ActionScript version&lt;/h3&gt;
&lt;p&gt;&lt;object data="/files/2009/test.swf" height="400" id="swf0a0b1" style="visibility: visible;" type="application/x-shockwave-flash" width="600"&gt;&lt;param name="wmode" value="opaque"/&gt;&lt;param name="menu" value="true"/&gt;&lt;param name="quality" value="high"/&gt;&lt;param name="bgcolor" value="#FFFFFF"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/2009/test.zip"&gt;source code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Methods used are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;str += concateString;&lt;/li&gt;
&lt;li&gt;str = str.concat(concateString);&lt;/li&gt;
&lt;li&gt;array.push(concateString); … str = array.join(“”);&lt;/li&gt;
&lt;li&gt;vector.push(concateString); … str = vector.join(“”);&lt;/li&gt;
&lt;li&gt;byteArray.writeUTFBytes(concateString); … str = byteArray.readUTFBytes(byteArray.length);&lt;/li&gt;
&lt;li&gt;byteArray.writeMultiByte(concateString,”us-ascii”); … str = byteArray.readMultiByte(str.length,”us-ascii”);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The result shows that fastest method is using &lt;code&gt;+=&lt;/code&gt;, but using
Array/Vector is still very close to it. Using ByteArray is slow and with
&lt;span class="caps"&gt;ASCII&lt;/span&gt; instead of &lt;span class="caps"&gt;UTF&lt;/span&gt;-8 is even slower…&lt;/p&gt;
&lt;p&gt;And all the methods are performed reasonably fast, what is slow is when
showing the resulting string on TextArea… It takes a few seconds! But
when it is drawn, run it again and it will become normal speed, maybe
there is some caching?&lt;/p&gt;
&lt;h3&gt;JavaScript version&lt;/h3&gt;
&lt;p&gt;I coded a JavaScript port too. &lt;a href="/files/2009/string-concatenation-methods-performace-test.html"&gt;See it here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Methods used are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;str += concateString;&lt;/li&gt;
&lt;li&gt;str = str.concat(concateString);&lt;/li&gt;
&lt;li&gt;array.push(concateString); … str = array.join(“”);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Interesting enough, the result is very similar to &lt;span class="caps"&gt;AS3&lt;/span&gt;. It is the
opposite of what we believe using the Array trick will let it performs
faster. &lt;code&gt;+=&lt;/code&gt; is the fastest in most cases, if not, that’s not much difference.&lt;/p&gt;
&lt;p&gt;I’ve only tested in &lt;span class="caps"&gt;IE8&lt;/span&gt;(Win), Firefox 3 (Win/Mac), Safari 4 (Win/Mac),
Chrome 3 (Win). The really really really interesting part is in Chrome
3, using the concat method of String is x7000 &lt;span class="caps"&gt;SLOWER&lt;/span&gt; than the other
two!! What are your results?&lt;/p&gt;</content><category term="experiment"></category><category term="Flash"></category><category term="JavaScript"></category></entry></feed>