|
Collection v4
Доделал 4-ю версию своего эпичного велосипеда:) Создал новый тред, т.к. по сравнению с прошлой версией было сделано оч много конфликтующих изменений.
https://github.com/kobezzza/Collection Что это и зачем: В JavaScript для массивов есть встроенные методы-итераторы, например, forEach, reduce и map и т.д. Их очень удобно использовать и они делают наш код нагляднее. Данная либа позволяет юзать все те же методы + дополнительные для любых типов данных, а не только для массивов. Также итераторы в Collection работают значительно быстрее нативных. Также в этой либе реализован простой интерфейс для работы с хранилищами данных: localStorage, sessionStorage, indexedDB. Итак: По сравнению с прошлой версией было выпилено много лишнего (теперь сжатая либа - это всего 11.3 килобайта). Теперь либа позиционируется как единый и очень навороченный API для функциональной работы с коллекциями данных, а не как блендер из кучи всего (как было раньше:) ). Реализован единый прозрачный API для работы с хранилищами данных (localStorage, sessionStorage, indexedDB). Реализован свой собственный JIT компилятор для итераторов, который позволяет увеличить до 10-ти раз производительность в сравнении с нативными методами во всех современных браузерах (применяемые оптимизации не делают работу за JIT VM JavaScript, а наоборот: дополняют те вещи, которые не могут быть оптимизированы нативным JIT). В древних браузерах этот эффект может быть ещё выше. Переработаны интерфейсы методов для более простой и удобной работы. Код переписан на ECMAScript6 (с транслятором) :) Парочка примеров: // Перебор элементов в обратном порядке начиная с 5-го $C(document.querySelectorAll('.foo')).forEach(function (el) { ... }, { reverse: true, startIndex: 5 }); // Вернуть массив всех чётных элементов исходного массива $C([1, 2, 3, 4]).get(function (el) { return el % 2 === 0; }); // Cоздать новый объект на основе исходного, // {a: 2, b: 4} $C({a: 4, b: 16}).map(Math.sqrt); // Загрузить коллекцию foo из локального хранилища $C().load('foo'); О найденых багах пишите на гитхаб, вопросы можно задавать тут:) ЗЫ: про отвратительную историю коммитов в курсе, буду исправляться :) |
Было бы интересно послушать про оптимизации)
|
Цитата:
Т.е. методы Collection принимают оч много параметров-ограничений, вроде количество элементов в ответе и т.д. Эта информация учитывается при генерации оптимизированный функции, т.е. если нет необходимости это учитывать то логика проверки не войдёт. В функциях callback учитывается количество принимаемых параметров, наличие this, наличие возвращаемого значения и т.д. - эта информация также помогает построить оптимизированную функцию. Анализируется тип данных, например для массиво-подобных объектов по умолчанию используется for, как и для массивов вместо for in. После нормальной реализации в браузерах for of добавлю дополнительную поддержку итераторов. Фильтры анализируются более глубоко, вплоть до возможного инлайнинга. Инлайнингу почти всегда подвергаются функции-строки (вроде :el > 2), а также лямбда-функции (в теле которых сразу идёт return), но только если пройдёт проверка внешних зависимостей. Поощряется разбивать фильтры на множество атомарных и затем использовать композицию, вроде: .get('odd && unique || some') // и т.д. подробнее в доке Т.к. составные фильтры перед выполнением строят дерево логики и оптимизируют его для максимального инлайнинга. После всех оптимизаций составляется специальный ключ, который определяет вид применённых оптимизаций и в дальнейшем этот ключ может использоваться для схожий операций, т.е. оптимизация делается один раз. В браузерах дополнительно оптимизированные функции подключаются как внешние скрипты, что дополнительно увеличивает скорость работы и улучшает отладку (для node планирую добавить кеширование во внешний файл). Также ключи оптимизации в браузере сохраняются в локальном хранилище и при обновлении странице будут подключены как внешний скрипт, т.е. уже не будет необходимости в повторной оптимизации, причём ключи привязываются к домену, т.е. при повторном заходе на сайт оптимизация будет ещё сильнее. На примере проекта над которым я сейчас работаю замена нативных методов на Collection без внесения дополнительных оптимизация увеличило скорость работы всего сайта в 12-16 раз во всех браузерах. ЗЫ: Вот пример сгенерированных ключей http://screencast.com/t/M4IqYUqRNF ЗЫЗЫ: Ещё один слой оптимизации - это оптимизация и сжатие либы в GCC Adv Mode :) Хз что он там колдует, но после сжатия всё реально шустрее работает :) |
Цитата:
не особо вникал в код пока, но я так понял ты вообще не используешь встроенные циклы типа for при переборе, или как ты перебираешь то что передали? К примеру я передал массив , как он будет обработан и каким циклов перебран? |
Цитата:
Цитата:
|
Цитата:
Цитата:
вопрос по продвинутом сжатию, к примеру есть код (function (undef) { var local_name = "cache_module_", v_name = local_name + "cache_version"; function cache(params) { this.storage = sessionStorage; this.isUse = false; if(params.isLocal) { this.storage = localStorage; } } cache.prototype.get = function (id) { if(!this.isUse) return; try{ var obj = this.storage.getItem(local_name + id) return JSON.parse(obj); } catch(ignore) {} }; cache.prototype.set = function(key, data) { if(!this.isUse) return; setTimeout(function() { this.storage.setItem(local_name + key, JSON.stringify(data)); }.bind(this), 0) }; cache.prototype.removeItem = function(key) { this.storage.removeItem(local_name + key); }; cache.prototype.clear = function () { var storage = this.storage, key; for(var i = 0; i < storage.length; i++) { key = storage.key(i); if(~key.indexOf(local_name)) storage.removeItem(key); } } cache.prototype.init = function(parent, initObj) { var v; if(arguments.length != 2 || initObj.cacheVersion === undef) return; if(v = this.get(v_name) && v != initObj.cacheVersion) { this.clear(); } this.set(v_name, initObj.cacheVersion); this.isUse = true; }; Object.defineProperty(cache.prototype, "name", { value: "cache", writable: false }); window.Cache_module = cache; }()); // почему из него убираються прототипы и остаеться (function(){function b(){}Object.defineProperty(b.prototype,"name",{value:"cache",writable:!1});window.a=b})(); это из за того что они явно не используеться в коде? |
Цитата:
Цитата:
|
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Часовой пояс GMT +3, время: 09:51. |
|