|
|
|||||
Регистрация: Feb 2012
Сообщений: 1,540
|
|
|
|||||
Регистрация: Mar 2007
Сообщений: 319
|
псс, парень! не хочешь немного скорости?
package { import flash.display.Sprite; import flash.text.TextField; import flash.utils.getTimer; import flash.utils.setTimeout; /** * @author SlavaRa */ public class Main extends Sprite { public static const arr:Vector.<String> = new <String>["Ехал", "Грек", "а", "через", "рек", "у", "видит", "в", "е", "рак", "сунул", "руку", "за", "цап", "0"]; public static const str:String = "{0} {1}{2} {3} {4}{5}, {6} {1}{2} {7} {4}{8} {9}, {10} {1}{2} {7} {4}{5} {11}, {9} {12} {11} {1}{5} {13}!! {q} {{14}}"; public static const COUNT:int = 100000; public function Main () { super(); _field = new TextField(); _field.width = 800; _field.height = 600; addChild(_field); setTimeout(runTests, 1000); } private function runTests ():void { testNubideus(); testMikroAcse(); testSlavaRa(); testNooob(); } private var _field:TextField; private function testNubideus ():void { var stamp:int = getTimer(); for (var j:int = 0; j < COUNT; j++) { var result:String = ""; var openIndex:uint = 0; var closeIndex:uint = 0; var i:uint = 0; parse: while (true) { openIndex = str.indexOf("{", i) + 1; if (openIndex) { sl: for (i = openIndex; ; 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 < i){ var substr:String = str.substring(openIndex, i); result += str.substring(closeIndex, openIndex - 1) + arr[uint(substr)]; closeIndex = i + 1; } continue; } break; } result += str.substring(closeIndex, str.length); } _field.appendText("\ntestNubideus:" + (getTimer() - stamp)); _field.appendText("\n" + result); } private function testMikroAcse ():void { var stamp:int = getTimer(); for (var j1:int = 0; j1 < COUNT; j1++) { var res:String = ""; var current:String; var nesting:int = 0; for (var j:int = 0, l:int = str.length; j < l; j++) { var char:String = str.charAt(j); if (char == '{') { if (nesting == 0) { current = ""; } else { current += '{'; } nesting++; continue; } if (char == '}') { if (nesting == 1) { var parsed:Number = parseFloat(current); if (isNaN(parsed)) { res += "{" + current + "}"; } else { res += arr[parsed]; } } else { current += '}'; } nesting--; continue; } if (nesting == 0) { res += char; } else { current += char; } } } _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp)); _field.appendText("\n" + res); } private function testSlavaRa ():void { var stamp:int = getTimer(); for (var j:int = 0; j < COUNT; j++) { var result:String = StringTool.format(str, arr); } _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp)); _field.appendText("\n" + result); } private function testNooob ():void { var stamp:int = getTimer(); for (var j:int = 0; j < COUNT; j++) { var result:String = StringUtilsFast.format(str, arr); } _field.appendText("\ntestNooob:" + (getTimer() - stamp)); _field.appendText("\n" + result); } } } import flash.system.ApplicationDomain; import flash.utils.ByteArray; import avm2.intrinsics.memory.li32; import avm2.intrinsics.memory.li8; import avm2.intrinsics.memory.si32; class StringUtilsFast { private static const bytes:ByteArray = new ByteArray(); bytes.length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH; [Inline] public static function format (source:String, args:Vector.<String>):String { var mem:ByteArray = ApplicationDomain.currentDomain.domainMemory; ApplicationDomain.currentDomain.domainMemory = bytes; var ptr:int = 0; var n:int = source.length; for (var i:int = 0; i < n; i++) { si32(source.charCodeAt(i), ptr += 4); } var result:String = ""; var openIndex:int = -1; i = 0; n = ptr; while (i < n) { var charCode:uint = li32(i += 4); if (openIndex != -1) { if (charCode == 125) { var index:int = 0; var count:int = 1; for (var k:int = openIndex + 4; k < i; k += 4) { var code:uint = li32(k); if (code >= 48 && code <= 57) { index = index * count + (code - 48); count *= 10; continue; } index = -1; break; } if (index != -1) { result += args[index]; openIndex = -1; continue; } var h:int = i + 4; for (k = openIndex; k < h; k += 4) { result += String.fromCharCode(li32(k)); } openIndex = -1; continue; } if (charCode == 123) { for (k = openIndex; k < i; k += 4) { result += String.fromCharCode(li32(k)); } openIndex = i; continue; } continue; } if (charCode == 123) { openIndex = i; continue; } result += String.fromCharCode(charCode); } ApplicationDomain.currentDomain.domainMemory = mem; return result; } } 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; } } Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0} testMikroAcse:1335 Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}} testSlavaRa:2638 Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал testNooob:746 Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0} Последний раз редактировалось Nooob; 08.09.2014 в 20:33. |
|
|||||
Регистрация: Jan 2013
Сообщений: 322
|
> result += String.fromCharCode(
Nooob, прикрути substring, а то если увеличить расстояние между вставками, скорость упадет Цитата:
короче строка "{0} {} {" Цитата:
Последний раз редактировалось nubideus; 08.09.2014 в 21:12. |
|
|||||
Регистрация: Mar 2007
Сообщений: 319
|
ага, исправил
class StringUtils { [Inline] public static function format (source:String, args:Vector.<String>):String { var result:String = ""; var openIndex:int = -1; var charCount:int = 0; var n:int = source.length; var a:int = args.length; var i:int = 0; l3: if(i < n) { var char:String = source.charAt(i); if (openIndex != -1) { if (char == "}") { var start:int = openIndex + 1; if(start == i) { goto l1; } var argsIndex:int = 0; var tenths:int = 1; l2:if (start < i) { var code:uint = source.charCodeAt(start); if (code >= 48 && code <= 57) { argsIndex = argsIndex * tenths + (code - 48); tenths *= 10; start++; goto l2; } goto l1; } if (argsIndex < a) { result += source.substr(openIndex - charCount, charCount); charCount = 0; result += args[argsIndex]; openIndex = -1; i++; goto l3; } l1: result += source.substring(openIndex - charCount, i + 1); charCount = 0; openIndex = -1; i++; goto l3; } if (char == "{") { result += source.substring(openIndex - charCount, i); charCount = 0; openIndex = i; i++; goto l3; } i++; goto l3; } if (char == "{") { openIndex = i; i++; goto l3; } charCount++; i++; goto l3; } if(openIndex != -1) { result += source.substring(openIndex - charCount, i + 1); } else if (charCount > 0) { result += source.substr(i - charCount, charCount); } return result; } } var index:int = 0; var tenths:int = 1; while(start < end) { var code:uint = source.charCodeAt(start); if (code >= 48 && code <= 57) { index = index * tenths + (code - 48); tenths *= 10; start++; continue; } break; } x100000 Релиз: testNubideus:1082 testNooob:692 Дебаг: testNubideus:4162 testNooob:6135 в чем причина разницы в 10 раз в принипе понятно, но не понятно почему одни и те же алгоритмы в релизе кажут лучше чем в дебаге? в релизе есть NanoJIT? оверхед на хранение стека? разница GC? Последний раз редактировалось Nooob; 08.09.2014 в 22:52. |
|
|||||
Регистрация: Mar 2007
Сообщений: 319
|
не, решил попробовать просто, никогда раньше не пользовался, так как ситуаций не было. а тут не хотел просто ту же самую операцию вешать на continue goto, break goto.
|
|
|||||
Регистрация: Jan 2013
Сообщений: 322
|
x100000
Цитата:
package { import flash.display.Sprite; import flash.text.TextField; import flash.utils.getTimer; import flash.utils.setTimeout; /** * @author SlavaRa */ public class Main extends Sprite { public static const arr:Vector.<String> = new <String>["Ехал", "Грек", "а", "через", "рек", "у", "видит", "в", "е", "рак", "сунул", "руку", "за", "цап", "0"]; public static const str:String = "{0} {1}{2} {3} {4}{5}, {6} {1}{2} {7} {4}{8} {9}, {10} {1}{2} {7} {4}{5} {11}, {9} {12} {11} {1}{5} {13}!! {q} {{14}} {} {"; public static const COUNT:int = 100000; public function Main () { super(); _field = new TextField(); _field.width = 800; _field.height = 600; addChild(_field); setTimeout(runTests, 1000); } private function runTests ():void { testNubideus(); testMikroAcse(); testSlavaRa(); testNooob(); } private var _field:TextField; private function testNubideus ():void { var stamp:int = getTimer(); for (var j:int = 0; j < COUNT; j++) { var result:String = ""; var openIndex:uint = 0; var closeIndex:uint = 0; var i:uint = 0; parse: while (true) { openIndex = str.indexOf("{", i) + 1; if (openIndex) { var index:uint = 0; for (i = openIndex; ; i++ ) { var code:uint = str.charCodeAt(i); //if ((code + 2147483551 | 0) >= 2147483599) { if (code >= 48 && code <= 57) { index = index * 10 + (code - 48); continue; }else if (code === 125) { // if "}" break; } continue parse; } if (openIndex < i) { result += str.substring(closeIndex, openIndex - 1) + arr[index]; closeIndex = i + 1; } continue; } result += str.substring(closeIndex, str.length); break; } } _field.appendText("\ntestNubideus:" + (getTimer() - stamp)); _field.appendText("\n" + result); } private function testMikroAcse ():void { var stamp:int = getTimer(); for (var j1:int = 0; j1 < COUNT; j1++) { var res:String = ""; var current:String; var nesting:int = 0; for (var j:int = 0, l:int = str.length; j < l; j++) { var char:String = str.charAt(j); if (char == '{') { if (nesting == 0) { current = ""; } else { current += '{'; } nesting++; continue; } if (char == '}') { if (nesting == 1) { var parsed:Number = parseFloat(current); if (isNaN(parsed)) { res += "{" + current + "}"; } else { res += arr[parsed]; } } else { current += '}'; } nesting--; continue; } if (nesting == 0) { res += char; } else { current += char; } } } _field.appendText("\ntestMikroAcse:" + (getTimer() - stamp)); _field.appendText("\n" + res); } private function testSlavaRa ():void { var stamp:int = getTimer(); for (var j:int = 0; j < COUNT; j++) { var result:String = StringTool.format(str, arr); } _field.appendText("\ntestSlavaRa:" + (getTimer() - stamp)); _field.appendText("\n" + result); } private function testNooob ():void { var stamp:int = getTimer(); for (var j:int = 0; j < COUNT; j++) { var result:String = StringUtilsFast.format(str, arr); } _field.appendText("\ntestNooob:" + (getTimer() - stamp)); _field.appendText("\n" + result); } } } import flash.system.ApplicationDomain; import flash.utils.ByteArray; import avm2.intrinsics.memory.li32; import avm2.intrinsics.memory.li8; import avm2.intrinsics.memory.si32; class StringUtilsFast { [Inline] public static function format (source:String, args:Vector.<String>):String { var result:String = ""; var openIndex:int = -1; var charCount:int = 0; var n:int = source.length; var a:int = args.length; var i:int = 0; l3: if(i < n) { var char:String = source.charAt(i); if (openIndex != -1) { if (char == "}") { if(openIndex == i) { goto l1; } var argsIndex:int = 0; var count:int = 1; var k:int = openIndex; l2:if (k < i) { var code:uint = source.charCodeAt(k); if (code >= 48 && code <= 57) { argsIndex = argsIndex * count + (code - 48); count *= 10; k++; goto l2; } goto l1; } if (argsIndex < a) { result += source.substr(openIndex - charCount - 1, charCount); charCount = 0; result += args[argsIndex]; openIndex = -1; i++; goto l3; } l1: result += source.substring(openIndex - charCount - 1, i + 1); charCount = 0; openIndex = -1; i++; goto l3; } if (char == "{") { result += source.substring(openIndex - charCount - 1, i); charCount = 0; openIndex = i + 1; i++; goto l3; } i++; goto l3; } if (char == "{") { openIndex = i + 1; i++; goto l3; } charCount++; i++; goto l3; } return result; } } 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; } } Цитата:
идею бессовестно урал, зато нашел баг. допустим строка 123: 0 * 1 + 1 1 * 10 + 2 12 * 100 + 3 = 1203 можно просто умножать на 10: 0 * 10 + 1 1 * 10 + 2 12 * 10 + 3 = 123 кстати у тебя последняя открытая скобка игнорится |
|
|||||
Регистрация: Mar 2007
Сообщений: 319
|
nubideus, ну всё, теперь я думаю что это самый быстрый вариант =)
|
Часовой пояс GMT +4, время: 07:19. |
|
« Предыдущая тема | Следующая тема » |
|
|