Pull to refresh

Comments 25

// функция-блок
blocks[‘my-block’] = function(arg1, arg2) { /* ... */ }

// функция-элемент – может быть обычным хелпером
//  или может генерировать часть ответа функции-блока
blocks[‘my-block__elem’] = function(arg1, arg2) { /* ... */ }

В то время как весь мир переходит на статическую типизацию, вы используете текстовые ключи :-D


Может посмотрите в эту сторону?


// функция-блок
function $my_block (arg1, arg2) { /* ... */ }

// функция-элемент – может быть обычным хелпером
//  или может генерировать часть ответа функции-блока
function $my_block__elem (arg1, arg2) { /* ... */ }

Или даже в эту:


class $my_block extends $ya_bem {
    constructor (arg1, arg2) { /* ... */ }

    elem (arg1, arg2) { /* ... */ }
}

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


// deskpad
priv('my-block', {
    main(data) {
        let bemjson;

        // ...

        return bemjson;
    },

    elem1(data) {
        // ...
    }
};

// desktop
priv('my-block', {
    elem2(data) {
        // ...
    }
};
Ну, то есть другими словами, пока весь мир переходит на статическую типизацию, вы используете текстовые ключи и планируете использовать из в будущем?

Статическая типизация в чем? В том, чтобы вместо строковых литералов использовать языковые идентификаторы? Общий, "статический" механизм работы классов мы планируем использовать, но из-за ограничений в их нативной поддержке придется оставить строковые ключи

Пока не хотим усложнял сборку добавлением транспайлеров

Подскажите, давно не писал на js: а какими же должны быть ключи в объекте?

Почти все базовые типы — строки, бул, числа, объекты, функции, массивы (символы почему-то не могут). Но все приводятся к строке:


hash = {};
hash[1] = 1;
hash['s'] = 2;
hash[function(){}] = 3;
hash[[]] = 4;
hash[{}] = 5;
hash[true] = 6;
hash[Symbol('xyz')] = 7;

console.log(Object.keys(hash));
// [ '1', 's', 'function (){}', '', '[object Object]', 'true' ]

console.log(Symbol.for('xyz') in hash);
// false
символы почему-то не могут

не понял, что вы имеете ввиду:


hash = {}; 
sym = Symbol('test');
hash[sym] = 2;
sym in hash // true
hash[sym] // 2
sym === sym // true
Symbol.for('test') === sym // false
// но
customSym = Symbol.for('custom') // Symbol(custom)
customSym === Symbol.for('custom') // true
Symbol.for('custom') === Symbol.for('custom') // true

Но все приводятся к строке

кроме Symbol

Почему-то думал, что hash[sym] и hash[Symbol.for('test')] — это одинаково должно работать. Мой косяк.


В таком случае, Symbol тоже может быть ключом, но не будет перечислен в Object.keys.

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

Я тоже не понимаю, что имеет в виду shergin, говоря о статической типизации

Есть маленький лайфхак: можно сконвертировать весь вывод профилировщика в JSON-формат и ходить по этому дереву себе. Я в свое время так писал простенькую утилитку, которая определяла, в каких файлах интерпретатор проводит больше всего времени, и шел оптимизировать их.

По сути мы это и сделали, только собрали кумулятивную величину для каждой функции внутри обработки одного запроса и вывели медианы. Все это на большой выборке из реальных production-логов

о. А я идиот и не знаю чем читал. Глубоко извиняюсь :)

Сорян, тогда я не понял, что хачит лайфхак

Для инструментирующего профилирования есть еще вот такое готовое решение (правда только для ES5). Там правда понавороченнее будет код, чем тот, что в примерах :)

А поделитесь, находили ли вы способ более-менее быстрого профилирования в боевых условиях? Например тот же njstrace существенно замедляет работу больших приложений, причем настолько существенно, что кроме как на тестовом стенде его применять невозможно.

До NJSTrace руки честно не дотянулись, а потом вышло выделенное на задачу время.


Поленился писать об этом в основной части, исправляюсь. Только что замерил время работы сервера под обстрелом без профилирования и с включенным профилированием в двух вариантах. В итоге: Instrumentation (обертка PRIV-ов с замером времени) дает +2.7% ко времени работы, а Sampling (v8-profiler) — это +114.7%


В боевых условиях можно использовать только "обертку", остальное только в тестовом стенде.

Небольшая подсказка — process.hrtime умеет сам показывать разницу между двумя своими вызовами — достаточно передать аргументом предыдущее значение.

var t1 = process.hrtime();

doSomething();

var t2 = process.hrtime( t1); //будет такой же массив с разницей между t2 и t1 в таком же формате [sec, nanosec]


И нет ли ошибки в коде nano? умножать на 1e9 вроде надо второй элемент массива.

Крутяк, про аргумент в hrtime упустил в доке. Спасибо.


Нет, ошибки в коде нет

Ошибка в коде есть. Double, который используется для хранения чисел в JS в принципе не способен вместить наносекунды – разрядности не хватит.
Другое дело, что для текущей задачи доступной точности достаточно.

Да, как-то так. Тем более hrtime возвращает время не с 1970

Можно и мы поделимся своим совсем небольшим опытом профилирования?

Для инструментирующего профилирования есть еще вот такое готовое решение (однако, только для ES5). Там правда «чуть по сложнее» будет код, чем тот, что в примерах выше :)

Можно также попробовать VTune. Недавно в node.js добавили его поддержку, правда требует пересборки node.js. Детали как пользовать — в этом видеодокладе. Для некоммерческого использования, open source проектов и студентов это бесплатно. Там как раз используется сэмплирование с помощью процессора и overhead небольшой (контролируется), плюс видно все сразу и нативный код и JavaScript.

Да, про njsTrace уже было выше. А на VTune было бы интересно посмотреть в контексте ноды, спасибо за инфу

Sign up to leave a comment.