Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Масксимально быстрая загрузка из Zip (http://www.flasher.ru/forum/showthread.php?t=206501)

morgenshtern 07.02.2014 11:18

Масксимально быстрая загрузка из Zip
 
Привет. Имеется старлинг приложение, которое загружает упакованные в zip (без сжатия) ресурсы через ZipFile (от nochump) и из него получает битмапы через loadBytes для последующего конвертирования в текстуры.
Код AS3:

var data:ByteArray = zipFile.getInput(zipFile.getEntry('имя_файла'));
loader.loadBytes(data);

Картинок грузится за раз около 400, и последовательное извлечение (по комплиту от loadBytes) довольно долгое, значительно дольше чем загрузка самого архива по инету.

Если же в цикле всю экстракцию инициировать - занимает 3 секунды, но вешает намертво приложение на это время (анимация в прелоадере фризится).

Основное время занимает конечно zipFile.getInput(zipFile.getEntry('имя_файла')), loadBytes и последующее создание битмапов проходит значительно быстрее.

С архивами в as3 до этого работать не приходилось, но хочется и быстро, и без фризов :)
Возможно, посоветуете какие библиотеки для работы с zip, более производительные и удобные?

illuzor 07.02.2014 11:57

Вряд-ли время распаковки получится сильно сократить.
Попробуйте искать библиотеки, которые написаны на c/c++ и портированы на флеш через alchemy.

3 секунды - время небольшое. Можно попробовать вынести распаковку в фоновый воркер, тогда фризов интерфейса не будет.

morgenshtern 07.02.2014 12:38

Так вот и хотелось узнать результаты сравнительных бэнчмарков разных либ :)
Архив то у меня без сжатия, почему так долго то. Возможно стоит смотреть в сторону хранения/извлечения пнгшек из sfw?

caseyryan 07.02.2014 12:43

Воркеры это вообще лажа ужасная. Как я понял, адоби на них забили частично, и вряд ли удастся комфортно разрабатывать что-то с воркерами.

Недавно сталкивался с такой же проблемой, и решил ее без воркеров. Распаковка стала чуть дольше, зато приложение не вешает совершенно, и все анимации будут работать. В общем, суть в том, чтобы распаковку делать не в цикле, и покадрово и или по таймеру

В общем, вот такой класс набросал
Код AS3:

package  {
 
 
        import flash.events.Event;
        import flash.events.EventDispatcher;
        import flash.events.TimerEvent;
        import flash.utils.ByteArray;
        import flash.utils.Timer;
        import nochump.util.zip.ZipEntry;
        import nochump.util.zip.ZipFile;
 
        public class ZipUnpacker extends EventDispatcher {
 
                private var _iter:                        int                                        = 0;
                private var _totalEntries:        int                                = 0;
                private var _zipEntries:        Array/*ZipEntry*/        = null;
                private var _timer:                        Timer                                = null;
                private var _zipFile:                ZipFile                                = null;
                private var _byteArrays:        Array/*ByteArray*/        = [];
 
                public function ZipUnpacker(zipFile:ZipFile) {
 
                        _zipFile                = zipFile;
                        _zipEntries                = _zipFile.entries;
                        _totalEntries        = _zipEntries.length;
                }
                public function unpack():void {
                        _timer                        = new Timer(12, _zipEntries.length +1);
                        _timer.addEventListener(TimerEvent.TIMER, onTimer);
                        _timer.start();
                }
 
                private function onTimer(e:TimerEvent):void {
                        // за один тик распаковываем 10 входов, если надо по одному, то просто убираем цикл
                        for (var i:int = 0; i < 10; i++) {
                                var percent:        int                = (_iter / _totalEntries) * 100;
                                //trace(percent); // тут можно процент распаковки показывать
 
                                var entry:                ZipEntry        = _zipEntries[_iter];
                                var name:                String                = entry.name;
                                var byteArray:        ByteArray        = _zipFile.getInput(entry);
 
                                var indexOfDot:        int                = name.lastIndexOf(".");
                                if (indexOfDot > -1) {                                                                                                                                        // значит в названии есть расширение
                                        var indexOfSlash:        int        = name.lastIndexOf("/") + 1;
                                        var fileName:                String        = name.substr(indexOfSlash, indexOfDot - indexOfSlash);
                                }
                                if (byteArray.bytesAvailable > 0) {
                                        _byteArrays.push(byteArray);
                                }
                                _iter++;
                                if (_iter >= _totalEntries) {
                                        _timer.reset();
                                        _timer.removeEventListener(TimerEvent.TIMER, onTimer);
                                        _timer                = null;
 
                                        dispatchEvent(new Event(Event.COMPLETE));
                                        break;
                                }
                        }
                }
        }
 
}

Передаем в конструктор архив, и ждем события complete.

Распаковывает он все это в байт массивы и помещает в массив. Естественно, в таком виде их вряд ли используешь, поэтому тут уж дальше кому что надо. У меня есть специальный класс обертка, в котором массив превращается в картинку через Loader.loadBytes() так же в этом классе хранится название ввода из архива, чтобы как-то это потом идентифицировать

Работает все так:
Код AS3:

var zipUnpacker:ZipUnpacker = new ZipUnpacker(myLoadedZip);
zipUnpacker.addEventListener(Event.COMPLETE, onZipUnpackComplete);
zipUnpacker.unpack();


morgenshtern 07.02.2014 12:47

Спасибо, как раз начал писать распаковку пачками.
Все сразу - быстро, но вешает приложение, по одному - нереально долго.
Пачки наверное в самый раз будут :)

Добавлено через 36 минут
Мде... Проблем вовсе не в коде или тормозной либе :D
Тотал перепаковывает архив при изменении его содержимого, добавляет 2% сжатия :wacko:
Перепаковал заново без сжатия винраром - время распаковки 70 мс в цикле и 380 пачками по 10. Кстати, с "обычным" сжатием то же самое извлекается почти 9000 мс...


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

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