Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Collection v4 (https://javascript.ru/forum/project/44796-collection-v4.html)

kobezzza 02.02.2014 14:41

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');


О найденых багах пишите на гитхаб, вопросы можно задавать тут:)

ЗЫ: про отвратительную историю коммитов в курсе, буду исправляться :)

melky 02.02.2014 15:13

Было бы интересно послушать про оптимизации)

kobezzza 02.02.2014 15:41

Цитата:

Сообщение от melky (Сообщение 295387)
Было бы интересно послушать про оптимизации)

Есть несколько слоёв оптимизации: самая очевидная и самая простая - это анализ параметров запроса.

Т.е. методы 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 :) Хз что он там колдует, но после сжатия всё реально шустрее работает :)

cyber 03.02.2014 17:46

Цитата:

Сообщение от kobezzza
сжатие либы в GCC Adv Mode

для тех кто в танке, можно обьянсть как это?)

не особо вникал в код пока, но я так понял ты вообще не используешь встроенные циклы типа for при переборе, или как ты перебираешь то что передали?
К примеру я передал массив , как он будет обработан и каким циклов перебран?

kobezzza 03.02.2014 18:08

Цитата:

Сообщение от cyber (Сообщение 295612)
для тех кто в танке, можно обьянсть как это?)

Ну это сжатие в продвинутом режиме closure compiler, для этого нужно спецом под него код писать.

Цитата:

Сообщение от cyber (Сообщение 295612)
не особо вникал в код пока, но я так понял ты вообще не используешь встроенные циклы типа for при переборе, или как ты перебираешь то что передали?
К примеру я передал массив , как он будет обработан и каким циклов перебран?

Как не использую? как раз его и использую) Если передал массив, строку или массивоподобный объект (например HTMLCollection) то буит простой for, для остальных for in

cyber 03.02.2014 19:00

Цитата:

Сообщение от kobezzza
Ну это сжатие в продвинутом режиме closure compiler, для этого нужно спецом под него код писать.

а понял, просто не знал что он так называеться. Под него довольно сложно писать

Цитата:

Сообщение от kobezzza
Как не использую? как раз его и использую) Если передал массив, строку или массивоподобный объект (например HTMLCollection) то буит простой for, для остальных for in

а, твоя реализация быстрее forEach и медленее 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})();


это из за того что они явно не используеться в коде?

kobezzza 03.02.2014 19:14

Цитата:

Сообщение от cyber (Сообщение 295620)
а, твоя реализация быстрее forEach и медленее for?)

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

Цитата:

Сообщение от cyber (Сообщение 295620)
вопрос по продвинутом сжатию, к примеру есть код
это из за того что они явно не используеться в коде?

Да, для продвинутого сжатия нужно писать специальный jsdoc анотации.

nerv_ 03.02.2014 20:21

Цитата:

Сообщение от kobezzza
Доделал 4-ю версию своего эпичного велосипеда

молодец) Добавь в начало первого поста "что это" и "зачем оно нужно" в двух словах. Иначе все
Цитата:

Сообщение от kobezzza
По сравнению с прошлой версией

не имеют смысла, т.к. не понятно о чем идет речь.

cyber 03.02.2014 20:25

Цитата:

Сообщение от kobezzza
Да, для продвинутого сжатия нужно писать специальный jsdoc анотации.

где можно по читать как это замутить?)

kobezzza 03.02.2014 20:27

Цитата:

Сообщение от nerv_ (Сообщение 295637)
молодец) Добавь в начало первого поста "что это" и "зачем оно нужно" в двух словах. Иначе все

не имеют смысла, т.к. не понятно о чем идет речь.

Исправил:)

kobezzza 03.02.2014 20:30

Цитата:

Сообщение от cyber (Сообщение 295641)
где можно по читать как это замутить?)

100 раз кидал уже эту ссылку: https://developers.google.com/closur...s-for-compiler

(это официальная дока closure compiler)

cyber 03.02.2014 20:59

kobezzza, а почему не используешь объект для передачи параметров?

kobezzza 03.02.2014 21:18

Цитата:

Сообщение от cyber (Сообщение 295671)
kobezzza, а почему не используешь объект для передачи параметров?

Перечитай приведённые мною примеры и доку:
https://github.com/kobezzza/Collecti...%D 0%BE%D0%B2

Цитата:

Приставка opt_ означает, что параметр является опциональным (соглашение о написание кода на JavaScript от Google). Параметр opt_filter (или просто filter) во всех итераторах может быть представлен как объект входных параметров, т.е.:
{
    filter,
    id,
    mult,
    count,
    from,
    startIndex,
    endIndex,
    reverse,
    inverseFilter,
    notOwn,
    live,
    useForIn,
    vars,
    context
}


т.е. использую.

Для внутренних вызовов юзается вызов с перечислением параметров, т.к. это работает быстрее, а для конечного использования конечно можно использовать объекты-параметры, если нужно.

melky 03.02.2014 23:36

Цитата:

Сообщение от kobezzza
Ещё один слой оптимизации - это оптимизация и сжатие либы в GCC Adv Mode Хз что он там колдует, но после сжатия всё реально шустрее работает

только замучаешься warning'и фиксить

Plovr тоже ничё так :)

cyber 04.02.2014 00:31

kobezzza, не могу понять как сделать что класс не переименовывало, пробывал ставить @constructor но не помогает
(function () {
  /**
  @constructor - пробывал так
 */
  function constr() {// сохранить имя constr

  }

  window.Constr = constr
}())


Цитата:

Сообщение от melky
только замучаешься warning'и фиксить

да ладно, все го то по 1й ошибки на каждые 10 строк кода:)

kobezzza 04.02.2014 09:41

Цитата:

Сообщение от cyber (Сообщение 295704)
kobezzza, не могу понять как сделать что класс не переименовывало, пробывал ставить @constructor но не помогает
(function () {
  /**
  @constructor - пробывал так
 */
  function constr() {// сохранить имя constr

  }

  window.Constr = constr
}())

Ну @constructor тут не причём.

Во первых: http://javascript.ru/optimize/google...d-optimization

Во вторых: @expose
https://developers.google.com/closur...s-for-compiler

Ну и в третьих просто глянул бы, как сделано у меня:
https://github.com/kobezzza/Collecti.../core/core.jsn

(this.Collection; и this.$C; - это для поддержки автокомплита в WebStorm)

kobezzza 04.02.2014 09:43

Цитата:

Сообщение от melky (Сообщение 295693)
только замучаешься warning'и фиксить

Я в своё время оч заморочился, что сейчас пишу без проблем под GCC, ну а ваще да - это гемор:)

melky 04.02.2014 11:19

Цитата:

Сообщение от kobezzza
Во вторых: @expose

нини.

вот как у тебя, так и надо. (про строковые имена):
global['Collection']

kobezzza 04.02.2014 11:23

Цитата:

Сообщение от melky (Сообщение 295754)
нини.

Почему? Я юзаю @expose для экспорта внешних (публичных) методов либы, т.к. не надо писать убогий ['...'] (код в первую очередь должен хорошо читаться), тем более многие публичные методы юзаются внутри и я не хочу думать о том: "забыл ли я экранировать название".

Либа жмётся и нужные методы внешние, а все "издержки" 100% закрываются gzip, т.е. нет никакой разницы. Если я жму либу вместе с проектом, то пред сжатием я дополнительно вырезаю @expose (replace(/@expose/gm, '') в скрипте сборки) и всё (или написать файл экстерн, но это даст хуже сжатие).

А вот если я юзаю экспорт как ['...'], то при сжатии с проектом уже без файла экстерна не обойтись, и сжатие будет хуже.

***

Если я пишу ['...'] то это означает что всегда-всегда это свойство должно быть с таким именем.

Вот пример: https://github.com/kobezzza/Collecti...rs.storage.jsn

Свойство Collection.Drivers.Storage должно быть доступно при использовании либы как "внешнего скрипта", но при сжатии вместе с проектом должно сжиматься, поэтому я юзаю @expose.

А свойства 'indexedDB', 'localStorage' и т.д. должны быть такими всегда, поэтому я экспортирую их в кавычках.

Например: global['Collection'] сделан так не спроста, т.к. Collection фигурирует в генерируемых скриптах в рантайме, т.е. всегда должны быть именно таким.

Разумеется я читал:

Цитата:

@expose should never be used in library code, because it will prevent that property from ever getting removed.
Но это просто напоминание: мол думайте, что делаете и всё.

melky 04.02.2014 11:57

kobezzza,



Генерирует, по-моему, такой код:

goog.exportProperty( %OBJECT% , "%PROP_NAME%", %PROP_VAL%);


Исходник:

/**
 * Exports a property unobfuscated into the object's namespace.
 * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);
 * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);
 * @param {Object} object Object whose static property is being exported.
 * @param {string} publicName Unobfuscated name to export.
 * @param {*} symbol Object the name should point to.
 */
goog.exportProperty = function(object, publicName, symbol) {
  object[publicName] = symbol;
};


Использование:


/** @export */
MYOBJ.MYPROP = 'FOO'



Цитата:

Сообщение от kobezzza
А свойства 'indexedDB', 'localStorage' и т.д. должны быть такими всегда, поэтому я экспортирую их в кавычках.

они, вроде, прописаны в экстернах и включены в компилер.

kobezzza 04.02.2014 12:04

melky, я в курсе про это, только где аргументы против @expose ?:) Юзать его можно, юзать его удобно, но просто когда его юзаешь нужно думать. Иначе бы его просто не было:)

kobezzza 04.02.2014 12:06

Цитата:

Сообщение от melky (Сообщение 295759)
они, вроде, прописаны в экстернах и включены в компилер.

Это частные случай, хранилище может называться хоть superStorage и реализовывать драйвер для хранения как угодно.

Вид хранилища у меня задаётся как Storage.lib = '...' поэтому нужно такое эскпортирование.

melky 04.02.2014 12:55

Цитата:

Сообщение от kobezzza (Сообщение 295761)
melky, я в курсе про это, только где аргументы против @expose ?:) Юзать его можно, юзать его удобно, но просто когда его юзаешь нужно думать. Иначе бы его просто не было:)

@export :
Y.prototype.t = function(a) {
    /* A CODE */
};
Y.prototype.FOO= Y.prototype.t;


@expose :
Y.prototype.FOO = function(a) {
    /* A CODE */
};


разница - в использовании. при экспорте использование - это Y.t, при expose - Y.FOO

Ну и исчо при компилировании некоторые методы выносятся в функции.

У меня был метод без аругментов.
Obj.foo = function () {  alert(this.bar) }
// Используется так :
Obj.foo();


Теперь он стал такой функцией :

function foo (a) {
    alert(a.bar)
}
// Используется так :
foo(this);


Хотя как и экспорты, expose эту фишку убивает (проверил сейчас).

Наверное, наш спор похож на "табы VS пробелы" и похожие, но у меня плохое предчувствие насчёт @expose, поэтому и не юзаю :)

melky 04.02.2014 13:01

kobezzza, вся документация находится в Readme.md ?

kobezzza 04.02.2014 13:03

Цитата:

Сообщение от melky (Сообщение 295769)
kobezzza, вся документация находится в Readme.md ?

Ну в ридми скорее описание основного (90%), сама дока в jsdoc.

melky 04.02.2014 13:29

Жаль, экстернов нет :( нипосжимать.

Попробую пощупать либу в след. проекте.

Кстати, хотел вот сделать pull request на unrolling loops, но не смог разобраться в исходниках и коммитах :Р

kobezzza 04.02.2014 13:37

Цитата:

Сообщение от melky (Сообщение 295772)
Жаль, экстернов нет :( нипосжимать.

Дык сжатая версия https://github.com/kobezzza/Collecti...lection.min.js

Кстати можно сделать свою сборку либы:

node build


А в файле build.jsn можно выкинуть не нужное.

Цитата:

Сообщение от melky (Сообщение 295772)
Кстати, хотел вот сделать pull request на unrolling loops, но не смог разобраться в исходниках и коммитах :Р

Ну кривые коммиты - это мой косяк, признаю, теперь буду за собой следить:)

А в исходниках что не понятно? Либа лежит в папке lib, итерационные методы в папке mult, все методы имеют jsdoc и описание.
Основные файлы имеют расширение .jsn (а .js - это файлы сгенериные транслятором).

Развёртка циклов профита не даёт, т.к. современные JS VM в этом плане оч прокачались и сами всё делают, я пробывал, но потом выпилил за ненадобностью:)

Но копать тут:
https://github.com/kobezzza/Collecti...t/compiler.jsn

cyber 05.02.2014 00:43

Цитата:

Сообщение от kobezzza
Ну и в третьих просто глянул бы, как сделано у меня:

даже не подозревал что ты выложил этот файл, спс что носом ткнул)

kobezzza 05.02.2014 08:56

Цитата:

Сообщение от cyber (Сообщение 295886)
даже не подозревал что ты выложил этот файл, спс что носом ткнул)

Ну вся либа вместе с исходником в открытом доступе, как обычно:)
Исходники в папке /lib/, сборка в папке /build/ (там также есть сжатая версия)

a.malitsky 06.02.2014 23:57

в форме офтопа
 
kobezzza, не могу понять - либа тебе нужна по основной работе? Или тебе хватает энтузиазма делать её вместе с докой просто для себя, обучения и с призрачной надеждой что она станет популярной? Вы тут такой жути понаписали про оптимизацию что я могу только догадываться о количестве потраченных человеко-часов. Уже прежней версии нет, сайт сгинул, так ещё раз всё с нуля на гитхабе теперь написано...

Лично я в одном проекте уже третью версию использовал, сейчас буду применять четвёртую во втором.

kobezzza 07.02.2014 09:28

Цитата:

Сообщение от a.malitsky (Сообщение 296418)
kobezzza, не могу понять - либа тебе нужна по основной работе? Или тебе хватает энтузиазма делать её вместе с докой просто для себя, обучения и с призрачной надеждой что она станет популярной? Вы тут такой жути понаписали про оптимизацию что я могу только догадываться о количестве потраченных человеко-часов. Уже прежней версии нет, сайт сгинул, так ещё раз всё с нуля на гитхабе теперь написано...

Лично я в одном проекте уже третью версию использовал, сейчас буду применять четвёртую во втором.

Либа нужна мне (я её очень активно юзаю в своих проектах), пишу в первую очередь для себя. К сожалению у меня нет времени на раскрутку своего творения (не, если кто хочет помочь, то милости прошу :) ).

Про связь с прошлой версией: я не изменил ни концепцию ни структуру, а просто выкинул те вещи, которые не показали своей полезности на практике, т.е. с большой долей вероятности переход будет простым. Были конечно некоторые дизайнерские изменения в интерфейсах, но их не очень много.

Основные ломающие изменения:
1) Был выкинут кластер шаблонизации, т.к. он эволюционировал в отдельный мой проект Snakeskin.
2) Был убран SQL-парсер, т.к. на практике применять его у меня как то не очень вышло.
3) Выкинуты методы: stat, groupStat, copy, move, т.к. их легко создать на основе get/map/reduce/
4) Выкинуты некоторые вспомогательные методы, вроде resetCollection, вряд ли их кто использовал
5) push_ методы переименованы в add_.

Т.е. основная цель версии 4 была уменьшить кодовую базу и добиться высокой скорости создания/выполнения.

Теперь про сайт:
по хорошему нужно создать сайт-описание на гитхабе, а домен collection-js.com привязать к нему, но у меня правда нет на это времени, поэтому я его прикрыл пока, т.к. там содержится устаревшая дока и написал полностью новую доку на гитхабе. Если честно не вижу особых проблем с этим, т.к. какая разница где лежит дока.

Пиши вопросы: я всегда оперативно на них отвечаю.

kobezzza 07.02.2014 15:29

Выпустил обновление 4.0.3 с исправлениями некоторых найденых ошибок.

cyber 07.02.2014 18:13

Цитата:

Сообщение от kobezzza
Либа нужна мне (я её очень активно юзаю в своих проектах), пишу в первую очередь для себя. К сожалению у меня нет времени на раскрутку своего творения (не, если кто хочет помочь, то милости прошу ).

запили статью на хабре с описанием как либа работает, я думаю будет лучшая реклама:)

kobezzza 07.02.2014 18:17

Цитата:

Сообщение от cyber (Сообщение 296539)
запили статью на хабре с описанием как либа работает, я думаю будет лучшая реклама:)

Говорю же, мне некогда, реал завал с делами :( Если бы написать статью это было пару часов, то тогда да, но на практике статья это минимум 3-4 полных дня (я говорю про себя конечно же:)).

ЗЫ: чёто у мя сёня день релизов :) запил 4.1.0, где были улучшены интерфейсы методов indexOf, lastIndexOf, _drop.

cyber 07.02.2014 18:25

kobezzza, хотел спросить насчет реализации forEach, по сути этот метод только перебирает массивы и только по числовым индексам (без использования Object.keys или for in), почему он тогда медленнее подобной реализации (в хроме критически медленне) и что может не так быть в этой реализации?

function each(arr, callback, context) {
        for(var i = 0, leng = arr.length; i < leng; i++) {
            if(context)
                callback.call(context, arr[i], i, arr);
            else
              callback(arr[i], i, arr);
        }
    }

сделал тест ради интереса http://jsperf.com/each-test-speed

kobezzza 07.02.2014 18:39

Цитата:

Сообщение от cyber (Сообщение 296543)
kobezzza, хотел спросить насчет реализации forEach, по сути этот метод только перебирает массивы и только по числовым индексам (без использования Object.keys или for in), почему он тогда медленнее подобной реализации (в хроме критически медленне) и что может не так быть в этой реализации?

function each(callback, context) {
    var leng = this.length;
        for(var i = 0; i < leng; i++) {
            if(context)
                callback.call(context, this[i], i, this);
            else
              callback(this[i], i, this);
        }
    }

Если я правильно тебя понял, то ты спрашиваешь, почему Array.prototype.forEach медленнее твоей реализации?

На самом деле нельзя сказать точно: медленнее или нет, т.к. в некоторых случаях JIT VM может эффективно скомпилить тот или иной код, а иногда нет. Лучше всех на данный момент с такими оптимизациями справляется ИЕ11.

Но в большинстве случаев падение скорости в нативных методах связано с тем, что стандартные массивы в JS - это на самом деле не массивы, а просто сахар над хешом.

Цитата:

Сообщение от cyber (Сообщение 296543)
сделал тест ради интереса http://jsperf.com/each-test-speed

https://github.com/kobezzza/Collecti...aster/profiler

Но на самом деле forEach не то место, где нужно смотреть, т.к. он быстрый сейчас везде. Большая разница в производительности на всяких выборках (всякие map, filter и т.д.).

cyber 07.02.2014 18:46

Цитата:

Сообщение от kobezzza
Но на самом деле forEach не то место, где нужно смотреть

ну если верить jspref то разница в 98% в хроме, это не значитель?:blink:

kobezzza 07.02.2014 18:48

Цитата:

Сообщение от cyber (Сообщение 296545)
ну если верить jspref то разница в 98% в хроме, это не значитель?:blink:

JSperf запускает твой тест в цикле, т.е. по сути у тебя тестируется не скорость forEach, а скорость forEach внутри цикла и это уже другая история:)

Посмотри тесты, что я тебе привёл по ссылке:
https://github.com/kobezzza/Collecti...r/forEach.html сравнения forEach
https://github.com/kobezzza/Collecti...filer/get.html get vs filter
https://github.com/kobezzza/Collecti...WithCycle.html get vs filter внутри цикла

Чтобы склонить репозитарий
git clone [url]https://github.com/kobezzza/Collection[/url]

cyber 07.02.2014 19:05

сделал тест
Цитата:

forEach 402
each 120
$C().forEach 129

kobezzza 07.02.2014 19:20

Цитата:

Сообщение от cyber (Сообщение 296553)
сделал тест

Странный результат, но всяко может быть :)
http://screencast.com/t/kTWjV15n5 вот результат замеров в 3-х браузерах на моей машинке.

Хотя повторюсь, что эти тесты все искусственные.


Часовой пояс GMT +3, время: 06:38.