StringBuilder en JavaScript : concatenation de String
En JavaScript, comme en .net ou ava, les strings sont immutables cela veut dire que l'objet ne peut pas être modifié après sa création.
Si nous oublions les optimisations des compilateurs, l'exécution du code ci dessous créé 3 instances de la classe String : "hello", "Cyril" et "hello Cyril".
var s = "hello";
s += " Cyril"
De ce fait, concaténer de nombreuses string va rapidement causer des problèmes de performance (mémoire et CPU) :
var d = new Date();
var s = '';
for(var i = 0; i < 100000; i++)
s += 'c';
Sys.Debug.trace(new Date() - d);
Le code ci-dessus met plus de 8 secondes sous IE7 et environ 150ms pour FF
Une des solutions consiste à utiliser un tableau afin de rajouter toutes les parties de String à l'intérieur puis d'utiliser la méthode join.
var d = new Date();
var s = [];
for(var i = 0; i < 100000; i++)
s[s.length] = 'c';
s = s.join('');
Sys.Debug.trace(new Date() - d);
Grâce à cette astuce, on passe de plus de 8000ms à 110ms pour IE7 et de 150ms à 140ms pour FF. Il est intéressant de constater que l'on utilise s[s.length] plutôt que la méthode s.push, en effet cette astuce se trouve plus rapide.
Vous pouvez également utiliser le tableau / StringBuilder dans une version allêgé, exemple :
var xaml = [
'<Canvas xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ',
' x:Name="NavigationTray" Visibility="Collapsed">',
' <Canvas.RenderTransform>',
' <TranslateTransform x:Name="SlideTransform" />',
' </Canvas.RenderTransform>',
' <Canvas.Resources>',
' <Storyboard x:Name="FadeStoryboard" Storyboard.TargetName="NavigationTray"',
' Storyboard.TargetProperty="Opacity">',
' <DoubleAnimation x:Name="FadeAnimation" />',
' </Storyboard>',
' <Storyboard x:Name="SlideStoryboard" Storyboard.TargetName="SlideTransform"',
' Storyboard.TargetProperty="Y">',
' <DoubleAnimationUsingKeyFrames> ',
' <SplineDoubleKeyFrame x:Name="SlideKeyFrame1" ',
' KeySpline="0,0 0,0" KeyTime="0:0:0" />',
' <SplineDoubleKeyFrame ',
' x:Name="SlideKeyFrame2" KeySpline="0,0 0,1" />',
' </DoubleAnimationUsingKeyFrames> ',
' </Storyboard>',
' </Canvas.Resources>',
'</Canvas>'
].join('');
Microsoft Ajax Library introduit même une classe toute faite : Sys.StringBuilder
L'équipe JScript à annoncé qu'on aura plus un tel écart de performances avec IE8 : Performance issues with "String Concatenation" in JScript.