x10000
testNubideus:141
testMikroAcse:227
testSlavaRa:174
testNooob:173
> Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!
> Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!
> {1{2}{3}{1}}
> {1годазавтрашний4}
> }{}{}{}{}{}{}{}[[[[]}{{}}]]}}{
> }{}{}{}{}{}{}{}[[[[]}{{}}]]}}{
testSlavaRa:
> "{{1}}", ["Юзернейм", "0", "года", "завтрашний", "только лишь все"]
> Юзернейм // wat
testMikroAcse:
>Привет {0}, тебе сегодня исполнилось
{{1}} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!
>Привет Юзернейм, тебе сегодня исполнилось
только лишь все года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!
testNooob: жааль что там только от 0 до 9, плюсик дает всего дополнительные 5% времени

Код AS3:
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.utils.setTimeout;
/**
* @author SlavaRa
*/
public class Main extends Sprite {
public static const COUNT:int = 10000;
public function Main() {
super();
_field = new TextField();
_field.width = 800;
_field.height = 600;
addChild(_field);
setTimeout(runTests, 1000);
}
private function runTests():void {
testNubideus();//testNubideus:27352
testMikroAcse();//testMikroAcse:33144
testSlavaRa();//testSlavaRa:23775
testNooob();//testNooob:26051
}
private var _field:TextField;
private function testNubideus():void {
var stamp:int = getTimer();
for (var j:int = 0; j < COUNT; j++) {
var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
var result:String = "";
var openIndex:int = -1;
var closeIndex:int = -1;
parse: while (true) {
openIndex = str.indexOf("{", openIndex + 1);
if (openIndex !== -1) {
sl: for (var i:uint = openIndex + 1; i < str.length; i++ ) {
switch(str.charAt(i)) {
case "0": case "1":
case "2": case "3":
case "4": case "5":
case "6": case "7":
case "8": case "9":
continue;
case "}":
break sl;
default:
continue parse;
}
}
if(openIndex + 1 < i){
var substr:String = str.substring(openIndex + 1, i);
result += str.substring(closeIndex + 1, openIndex) + arr[uint(substr)];
closeIndex = i;
}
}else {
result += str.substring(closeIndex + 1, str.length);
break;
}
}
}
_field.appendText("\ntestNubideus:" + (getTimer() - stamp));
}
private function testMikroAcse():void {
var arr:Array = ["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
var stamp:int = getTimer();
for (var j:int = 0; j < COUNT; j++) {
var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
var len:int = arr.length;
for(var i:int = 0; i < len; i++) {
str = str.split("{" + i + "}").join(arr[i]);
}
}
_field.appendText("\ntestMikroAcse:" + (getTimer() - stamp));
}
private function testSlavaRa():void {
var args:Vector.<String> = new <String>["Юзернейм", "4", "года", "завтрашний", "только лишь все"];
var stamp:int = getTimer();
for (var j:int = 0; j < COUNT; j++) {
var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
str = StringTool.format(str, args);
}
_field.appendText("\ntestSlavaRa:" + (getTimer() - stamp));
}
private function testNooob():void {
var stamp:int = getTimer();
for (var j:int = 0; j < COUNT; j++) {
var str:String = "Привет {0}, тебе сегодня исполнилось {1} {2}. Сегодня в {3} день могут смотреть не {4}. Не скучай, {0}!";
str = StringUtils.format(str, "Юзернейм", "4", "года", "завтрашний", "только лишь все");
}
_field.appendText("\ntestNooob:" + (getTimer() - stamp));
}
}
}
class StringTool {
[Inline]
public static function format(source:String, args:Vector.<String>):String {
for(var i:int = args.length; --i >= 0; ) {
var pattern:String = "{" + i + "}";
label: if(source.indexOf(pattern) != -1) {
source = source.replace(pattern, args[i]);
goto label;
}
}
return source;
}
}
class StringUtils
{
private static const regExp:RegExp = /{(\w)}/g;
private static var repl:Array;
public static function format(source:String, ...args):String
{
repl = args;
return source.replace(regExp, replaceFunc);
}
private static function replaceFunc(substr:String, group:int, i:uint, str:String):String
{
return repl[group];
}
}
+ без проверки на число, 115 мсек
ищет "{", потом ищет первую попавшуюся "}", arr[все что между ними].
если между ними ничего нет, то вставляется {}.

Код AS3:
var arr:Array = ["Юзернейм", "года", "завтрашний", "только лишь все"];
var str:String = "Привет {0}, тебе сегодня исполнилось {length} {1}. Сегодня в {2} день могут смотреть не {3}. Не скучай, {0}!";
var result:String = "";
var openIndex:int = -1;
var closeIndex:int = -1;
while (true) {
openIndex = str.indexOf("{", closeIndex + 1);
if (openIndex !== -1) {
var i:int = str.indexOf("}", openIndex + 1);
if (i === -1) {
break;
}
if(openIndex + 1 < i){
var substr:String = str.substring(openIndex + 1, i);
result += str.substring(closeIndex + 1, openIndex) + arr[substr];
}else {
result += "{}";
}
closeIndex = i;
}else break;
}
result += str.substring(closeIndex + 1, str.length);
trace(result); // Привет Юзернейм, тебе сегодня исполнилось 4 года. Сегодня в завтрашний день могут смотреть не только лишь все. Не скучай, Юзернейм!