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

kobezzza 19.06.2014 13:07

Выпустил апдейт 5.0.4. Значительно увеличена скорость работы pop / shift для простых объектов.

kobezzza 19.06.2014 18:41

Выпустил апдейт 5.0.5.

Реализовано кеширование сгенерированных циклов в файле для node.js.
Реализована оптимизация "холостых" итераций, т.е. без передачи параметров в callback.

$C({a: 1, b: 2}).forEach(function () {
    ...
});

$C({a: 1, b: 2}).forEach(function (el) {
    ...
});


Первый вариант теперь работает почти в 3 раза быстрее.

melky 19.06.2014 20:28

Цитата:

Сообщение от kobezzza (Сообщение 317282)
Выпустил апдейт 5.0.5.

Реализовано кеширование сгенерированных циклов в файле для node.js.
Реализована оптимизация "холостых" итераций, т.е. без передачи параметров в callback.

$C({a: 1, b: 2}).forEach(function () {
    ...
});

$C({a: 1, b: 2}).forEach(function (el) {
    ...
});


Первый вариант теперь работает почти в 3 раза быстрее.

почему работает эта оптимизация???

kobezzza 19.06.2014 20:37

Цитата:

Сообщение от melky (Сообщение 317297)
почему работает эта оптимизация???

Потому что el вычисляемый параметр, и в некоторых случаях довольно затратный (получение из цепочки прототипов и т.д.). На самом деле я просто добавил условие, что неиспользуемые параметры не только не передаются в callback, но и не вычисляются и это дало профит.

Конечно это оптимизация нужна очень редко, но все равно:)

kobezzza 30.06.2014 12:35

Сегодня приснился ещё один оптимизационный трюк, думаю смогу ускорить работы некоторых операций ещё процентов на 5-10 :)

melky 30.06.2014 14:58

не сравнивал скорость работы $C с fast.js?

kobezzza 30.06.2014 15:13

Цитата:

Сообщение от melky (Сообщение 318810)
не сравнивал скорость работы $C с fast.js?

Нет, но как раз собирался, но почти уверен, что Collection порвёт всех как тузик грелку :)

А если сравнивать с точки зрения алгоритмической сложности, тот тут Collection быстрее всех аналогов в N раз (где N количество операций), например:

filter1().filter2().map().slice(0, 10) // 4 операции + на slice потенциальный огромный оверхед

$C(...).map(calback, {filter: 'filter1 && filter2', from: 0, count: 10}) // никаких оверхедов, т.к. всё делается в один проход и операция сбросится после достижения count: 10


UPD: в релизе 5.1 (надеюсь сегодня сделаю) реализовал бешеную оптимизацию для обхода Map / Set. При сравнении с нативным for of разница примерно в 40 раз, а при обходе с reverse: true, то в N раз (где N - количество элементов в коллекции).

UPD:UPD:
Глянул код fast.js, результат мне уже известен :) Вообще все классические оптимизации, которые применяются в underscore, lodash, fast.js и т.д. по природе своей ущербны, т.к. они их делают в живом цикле и поэтому они всегда будут проигрывать Collection или нативным циклам. А вот Collection основан на хитрой кодогенерации, т.е. полученный цикл лишён не нужных для каждого конкретного случая оптимизаций и проверок и поэтому работает с максимальной эффективностью.

kobezzza 30.06.2014 20:08

Выпустил апдейт v5.1.0.

1) Исправлена критическая бага в методе remove;
2) Очень сильно увеличена производительность обхода Map / Set коллекций;
3) Улучшен модуль инлайнинга, что дало в некоторых случаях дополнительный профит;
4) Добавлена новая сборка Collection.core, которая включает в себя только 2 основных метода: forEach и extend и весит примерно 8кб в gzip;
5) Добавлен параметр chain для некоторых итерационных методов, который позволяет делать цепочки вызовов:

$C(...).map(..., {chain: true}).get()

kobezzza 20.07.2014 20:49

В планируемом обновление 5.2.0 добавлю новый контекстный метод yield (будет требоваться поддержка генераторов).

var result = $C({ ...очень большой объект... }).map(function (el, key, data, i) {
    this.$.i = this.$.i || 1;

    if (i === 1e6 * this.$.i) {
        this.$.i++;
        this.yield();
    }
});

$C.onFinish(result, function (value) {
    ...
});


Т.е. метод this.yield(); прерывает выполнение операции и возвращает объект:

{
    done: true / false,
    result: ...
}


Таким образом дробление сложной операции будет осуществляться очень просто. Работу над обновлением планирую начать сразу же, после окончания работа над Snakeskin 4.

kobezzza 21.07.2014 00:56

Также решил добавить 2 новых параметра для всех итеративных методов: iterations и onFinish

$C({ ...очень большой объект... }).forEach(function () { ... }, {
    iterations: 1e5,
    onFinish: function (value) { ... }
});


Т.е. каждые 1e5 итераций будет делаться прерывание и дальнейшая работа продолжиться на следующем итерационном цикле, а onFinish будет вызван, когда операция закончиться.

kobezzza 25.07.2014 14:11

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

Т.е. можно будет просто делать вызов $C и не думать, что он-что то там залочит.

$C(...).forEach(() => {
    ...
}, {worker: true})

$C(...).forEach(() => {
    ...
}, {worker: true})

$C(...).forEach(() => {
    ...
}, {worker: true})

$C(...).forEach(() => {
    ...
}, {worker: true})

... over 9000 операций


Количество активных операций и сами операции будит рулить планировщик, т.е. программисту об этом думать не нужно. Интерфейс обратного вызова будет спроектирован для совместной работы Promise и Async.

Самое приятное, что обновлённый движок Collection 5 позволит очень просто реализовать такую фичу с помощью оператора yield и у нас будет реальная альтернатива "тяжёлым потокам".

melky 25.07.2014 14:16

как изнутри планируешь это делать? nextTick ?

kobezzza 25.07.2014 14:25

Цитата:

Сообщение от melky (Сообщение 322732)
как изнутри планируешь это делать? nextTick ?

Для node - setImmediate. nextTick всегда добавляет операции в конец текущей итерации событийного цикла, а setImmediate переносит на следующий (в node 0.8 nextTick работал как setImmediate, но в node 0.10 это поведение изменили, а старый функционал вынесли в setImmediate).

Для браузера - setTimeout / setImmediate.

Сейчас алгоритм примерно такой планируется: планировщик следит, чтобы все worker операции $C не занимали более 80мс в одном итерационном цикле. По умолчанию у всех операций будет одинаковый приоритет, но его можно будет указывать явно.

kobezzza 20.08.2014 19:21

Сегодня написал первую тестовую версию реализации "лёгких потоков" на основе прерываний (yield) и планировщика с системой приоритетов.

Видео
Одновременно создаётся 50 forEach, в каждом по 1кк итераций и рандомно задаются приоритеты, т.е. общее количество итераций 50кк. Интерфейс не лочится и тормозов нет в принципе, результатом очень доволен. Думаю завтра / послезавтра зарелизю 5.2 версию с поддержкой.

Плюсы лёгкий потоков:
1) Нет затрат на создание;
2) Т.к. всё крутится в рамках главного потока, то прямой доступ к DOM и переменным замыкания (но тут нужно быть аккуратным, ибо моно выстрелить себе в ногу :));
3) Нет ограничений на количество создаваемых потоков (вернее есть, но равно количеству доступной памяти)

Минусы:
1) Требуется поддержка генераторов, т.е. пока работает только в ФФ, Хроме и компании, Ноде. В ИЕ ожидается с 12-й версии.
2) Теоретически возможно залочить поток, если сама итерация в цикле будет очень тяжёлой.

Алгоритм:

В рамках одной итерации событийного цикла JS все асинхронные процессы Collection могут забрать не более 60мс времени суммарно. У каждой задачи есть приоритет (по умолчанию normal)

var maxPriority = 40;
var priority = {
	'low'     : maxPriority / 8,
	'normal'  : maxPriority / 4,
	'hight'   : maxPriority / 2,
	'critical': maxPriority
};


Чем выше приоритет, тем выше вероятность, что данная задача попадёт в исполнение конкретного событийного цикла (но не 100%). Задачи с одинаковым приоритетом выбираются случайно с линейным распределением.

Определение выполняемых задач осуществляется на каждой итерации событийного цикла.

PS: цифорки на видео - это количество выделенных на операцию итераций событийного цикла.

kobezzza 21.08.2014 15:31

Пописав день с лёгкими тредами, я уже не понимаю, как я жил без них - это просто чудо!)

kobezzza 21.08.2014 20:01

Продумываю API вложенных потоков (т.е. поток созданный внутри потока).

Концепт такой:

$C(...).forEach(function (el) {
    // Метод wait приостановит выполнение родительского потока,
    // пока не выполнится дочерний и в качестве ответа вернёт результат работы дочернего потока
    this.wait($C(el).forEach(function () {
        ...
    }, {thread: true}));
}, {thread: true});


Также решил добавить метод .sleep который имеет следующий интерфейс:

sleep(time, opt_test, opt_interval)


*) время в мс
*) функция-проверка, если вернёт true, то поток "проснётся"
*) если true и opt_test вернёт false, то проверка будет проводится каждые time пока поток не проснётся

MallSerg 21.08.2014 21:01

Любопытно а зачем это?
кто и где это использует?

kobezzza 21.08.2014 21:22

Цитата:

Сообщение от MallSerg (Сообщение 326937)
Любопытно а зачем это?
кто и где это использует?

Что именно зачем? Потоки? Это настолько очевидно, что я даже не знаю что и написать :)

Что касается плюсов / минусов перед тяжелыми потоками, то я писал выше.

MallSerg 21.08.2014 22:09

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

kobezzza 21.08.2014 22:16

Ну дык:

https://github.com/kobezzza/Collection/wiki
https://github.com/kobezzza/Collecti...-Collection%3F

MallSerg 21.08.2014 22:29

Это я прочитал и для меня это пока выглядит бесполезно.
Просто думал что будет ссылка на реальный сайт где это реально используется.
Хотелось посмотреть на задачи в которых это приносит пользу и попробовать решить эти задачи на JS.
В общем покритиковать

Aetae 21.08.2014 22:42

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

kobezzza 21.08.2014 22:43

Это библиотека на каждый день. Чтобы её любить необходимо:

*) Любить функциональное программирование (не путать с процедурным);
*) Знать, что в JS помимо массивов есть ещё: Map, WeakMap, Set, WeakSet, Generator, TypedArrays, Object и т.д.

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

***

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

melky 22.08.2014 06:48

Цитата:

Сообщение от MallSerg
Хотелось посмотреть на задачи в которых это приносит пользу и попробовать решить эти задачи на JS.

:) ну ты зарядил , конечно

kobezzza 25.08.2014 11:30

Все выходные честно гамал и не написал ни строчки кода, поэтому перенёс релиз 5.2 на эту неделю :)

Gozar 25.08.2014 14:51

Цитата:

Сообщение от kobezzza
гамал

Во что? Я в поисках, полгода уже игру выбрать не могу.

kobezzza 25.08.2014 15:13

Цитата:

Сообщение от Gozar (Сообщение 327387)
Во что? Я в поисках, полгода уже игру выбрать не могу.

Перепрохожу Dragon Age Origin

l-liava-l 04.09.2014 14:56

Цитата:

Перепрохожу Dragon Age Origin
А мне майнкрафт нравится по сети, я там граблю караваны и сжигаю людей:D

kobezzza 04.09.2014 15:01

Цитата:

Сообщение от l-liava-l (Сообщение 328941)
А мне майнкрафт нравится по сети, я там граблю караваны и сжигаю людей:D

:D

Аркадий Укупник 06.09.2014 16:30

Map'ы и прочее кроме типизированных массивов эксперементальне технологии

kobezzza 06.09.2014 16:34

Цитата:

Сообщение от Аркадий Укупник (Сообщение 329223)
Map'ы и прочее кроме типизированных массивов эксперементальне технологии

Они являются частью стандарта ES6 и уже работают во всех современных браузерах и очень сильно упрощают жизнь, т.е. не использовать их по крайней мере глупо.

Аркадий Укупник 06.09.2014 16:35

ReferenceError: Map is not defined

Аркадий Укупник 06.09.2014 16:35

несовременный чот хром :(

kobezzza 06.09.2014 16:38

Цитата:

Сообщение от Аркадий Укупник (Сообщение 329227)
несовременный чот хром :(

В стабильной версии хрома необходимо включить в "about:flags" harmony. Ноду достаточно запустить в флагом --harmony.

Аркадий Укупник 06.09.2014 16:40

WeakMap & WeakSet есть

Аркадий Укупник 06.09.2014 16:43

Генераторы вещь нужная, а вот мапы бесполезны

Aetae 06.09.2014 16:43

Аркадий Укупник, свали флудить куда-нить в другое место, пока не забанили.(снова)

kobezzza 06.09.2014 16:45

Цитата:

Сообщение от Аркадий Укупник (Сообщение 329229)
WeakMap & WeakSet есть

Думаешь я не знаю? Но это не итерируемые коллекции по своей природе, однако ссылочные методы Collection поддерживают работу и с ними.

***

Я не понимаю смысл твоих постов. Есть конкретные вопросы - задавай, а флудить с видом "умника" иди в другое место.

kobezzza 06.09.2014 16:45

Цитата:

Сообщение от Аркадий Укупник (Сообщение 329230)
а вот мапы бесполезны

Ну-ну...

Аркадий Укупник 06.09.2014 16:48

Aetae, поясни за флуд?


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