Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Переменные в строке (http://www.flasher.ru/forum/showthread.php?t=208835)

GBee 08.09.2014 17:20

Цитата:

Не заменяет вовсе. Так сойдёт?
Нет. Дерзайте дальше :О)

MikroAcse 08.09.2014 17:24

Цитата:

Сообщение от GBee (Сообщение 1171728)
Нет. Дерзайте дальше :О)

Какой итог тебя устроит?

Nooob 08.09.2014 20:15

псс, парень! не хочешь немного скорости?
Код AS3:

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;
        }
}

testNubideus:1130
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}

testMikroAcse:1335
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}}

testSlavaRa:2638
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал

testNooob:746
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}

GBee 08.09.2014 20:25

Цитата:

Какой итог тебя устроит?
дано
"{0} {{1}}"
["1", "год"]

результат
"1 {год}"

nubideus 08.09.2014 21:01

> result += String.fromCharCode(
Nooob, прикрути substring, а то если увеличить расстояние между вставками, скорость упадет

Цитата:

x10000
testNubideus:546
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}
testMikroAcse:699
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}}
testSlavaRa:869
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал
testNooob:600
Ехал _____ Грек _____ а _____ через _____ рек _____ у, видит _____ Грек _____ а в _____ рек _____ е рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0}
+ у тебя пустые скобки считаются за ноль ({} = {0}), и игнорится { в конце
короче строка "{0} {} {"
Цитата:

testNubideus:64
Ехал {} {
testMikroAcse:49
Ехал {}
testSlavaRa:151
Ехал {} {
testNooob:39
Ехал Ехал

Nooob 08.09.2014 21:33

ага, исправил
Код AS3:

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;
        }
}

в целом, не важно как написано, главное чтобы не было преобразования строки в число, а преобразовывать по чар кодам.
Код AS3:

                                        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?

GBee 08.09.2014 22:56

Nooob, а goto вам что-то дает, или это привычка с других языков?

Nooob 08.09.2014 23:44

не, решил попробовать просто, никогда раньше не пользовался, так как ситуаций не было. а тут не хотел просто ту же самую операцию вешать на continue goto, break goto.

nubideus 09.09.2014 00:55

x100000
Цитата:

testNubideus:3256
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0} {} {
testMikroAcse:5090
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {{14}} {}
testSlavaRa:8296
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} Ехал {} {
testNooob:3643
Ехал Грека через реку, видит Грека в реке рак, сунул Грека в реку руку, рак за руку Греку цап!! {q} {0} {}
Код AS3:

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;
        }
}

Цитата:

Я вот только не понимаю, какие то адские различия между дебаг и релиз плеером
там после каждого переноса строки добавляются байты отладки, т.е. так получается потому что у тебя просто строк больше в коде. ну и мб charAt медленнее в дебаге

идею бессовестно урал, зато нашел баг.

допустим строка 123:
0 * 1 + 1
1 * 10 + 2
12 * 100 + 3
= 1203

можно просто умножать на 10:
0 * 10 + 1
1 * 10 + 2
12 * 10 + 3
= 123

кстати у тебя последняя открытая скобка игнорится

Nooob 09.09.2014 05:17

nubideus, ну всё, теперь я думаю что это самый быстрый вариант =)


Часовой пояс GMT +4, время: 19:56.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.