Pull to refresh
1
0
Багаев Дмитрий @bvdmitri

User

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

Но это конечно же в пространстве R^(m,n), но точно такие же рассуждения можно применить для матриц из целых чисел.
Каким образом последний пункт оказался в статье по оптимизации Angular приложений?
Сжатие именно это и делает. Причём не только для имён переменных, а для любых повторяющихся подстрок.


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

Ради простого примера:

function zip(arrays) {
  ...
}

function split(string) {
  ...
}


превратиться примерно в

function c(c) {
  ...
}

function cc(c) {
  ...
}


Что гораздо лучше сжимается чем исходный код любым алгоритмом сжатия. Причем алгоритмы минификации устроены таким образом, что результирующий код был compression-friendly.

Зачем его вообще добавлять тогда?


Например в зависимости от конфигурации могут получаться разные условия?

Усложнит отладку на проде вплоть до невозможности что-либо понять.


Вообще никак не усложняет отладку, потому что есть source-maps которые позволят вам даже в проде видеть оригинальный исходный код. Вообще не очень понимаю зачем дебажить продакшн, дебажьте дебажную сборку?

Может сломать релизную сборку своими предположениями об эквивалентности преобразований.


Не может (если вы следуете стандарту).

Замедлит деплой, порой в несколько раз.


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

Сделает стектрейсы с прода бесполезными.


Смотри пункт про отладку
Что вы несёте? Какой анализ минифицированного продакш кода? Анализируйте исходники на здоровье, или вы также сидите и анализируете байт-код джавы после компиляции? Анализируете нативные ассемблерные инструкции с кода?

Выгода от минификации колоссальна в масштабах всего интернета, если вы этого не понимаете, да ещё и утверждаете обратное, то и говорить не о чем.
Разница от минификации может быть в несколько раз, он не только пробелы уберет, но и пожмет все названия переменных и функций до 1-2ух символов, удалит неиспользуемый код, выделит повторяющиеся паттерны строк в отдельные переменные и много чего еще. И тот факт что Вы его не используете ни о чем не говорит, минификацию используют на сегодняшний день почти все (и правильно делают), что толку от вашего JS-интерпретатора, если он сможет открывать только Ваши сайты (не минифицированные).
Шансы того, что кто-то будет делать осмысленные вычисления, где понадобится точное значение тангенса пи/2 ещё меньше. Единственная осмысленная операция с ним, это деление на него, но тут достаточно очень большого числа (которое и выдаёт имплементация в chrome) чтобы получить число достаточно близкое к нулю.
Так вы пытаетесь решить «проблему» неточного представления PI/2 в компьютере и последующего неточно вычисления тангенса, но при этом говорите, что квадрат вычисляется неверно это нормально? Что за двойные стандарты? PI/2 тоже имеет «некоторую степень точности» и tan имеет «некоторую степень точности»

Если вы ожидаете, что tan(PI/2) должно возвращать бесконечность в компьютере, то я например ожидаю, что tan(PI/2-epsilon) не будет возвращать бесконечность, как вы будете решать эту «проблему»? Ведь в вашей имплементации все числа близкие к PI/2 будут давать бесконечность?
В моей реализации эти действия делает интерпретатор (программисту ни о чём беспокоиться не нужно), и в случае аргумента, близкого к Pi/2 вернётся ровно то, что программист ожидает получить (плюс бесконечность)


Окей, ваш интерпретатор готов гарантировать (я ожидаю получать правильный результат), что

(tan(PI/3))^2 == 3? Сомневаюсь, а то что
(tan(2*PI/3))^-2 == 3? Я могу таких примеров бесконечное множество приводить
В том, что тангенс вычисляется абсолютно неверно.


Я вам больше скажу, тангенс в компьютере вычисляется неверно для всех чисел. Вы также будете будете вводить интервалы для PI/3, чтобы получить «ровно» корень из трех?
Ну достаточно так же донести информацию до программиста, что PI/2 в компьютере представить невозможно (большинство и так об этом знают).

Ну вот мы и добрались до причины проблемы


В чем проблема то?
Вы уверены, что это проблема? Я вот вижу у вас проблему, что для у вас для многих чисел, которые попадают в ваш «очень малый интервал» вернется неправильное значение в виде бесконечностей или нулей.
Учитывая, что tan(pi/2) равно бесконечности, чем вас не устраивает выражение isFinite(tan(Math.PI / 2)) => false? Здравый смысл подсказывает, что это вполне правильное поведение.
Я бы так сказал, из названия класса DOMString для меня понятно следующее:

— эта самая строка в ходе парсинга и разбора не должна меняться — следовательно она константа
— использований метода типа fromMisc(«смотри, ма, я временный объект») не будет, так как это не имеет смысла (все таки кто из головы в коде будет придумывать DOMString?)

На мой взгляд нормальной реализацией тут было бы просто написать обертку над const char * и запретить вообще любое копирование и перемещение (=delete). Использовать const DOMString& и проследить чтобы время жизни объекта совпадало бы с вызовом функции парсинга. Если уж хочется сохранять какие то куски строк в токенах как делает автор, то можно оставить возможность отдавать константные слайсы этого DOMString (без выделения новой памяти).

Если юз-кейс отличается от описанного выше — легче использовать std::string
Каюсь, вы правы насчёт деструктора, там же в коде обычный std::string под капотом. По привычке подумал — раз есть свой string значит это обертка над raw char* — быстро проглядел и заметил что деструктор пустой. Но это тоже плохо на самом деле, убивается огромный пласт оптимизаций, move конструкторов написанных для std::string.

Для вашего примера с временными объектами придумали move-семантику.

Тем не менее вопрос об абсолютно неэффективной работе со строками и постоянным копированием (даже в тех функциях происходит два копирования которые можно, и нужно избегать) остаётся открытым
Почему у вас в коде абсолютно везде используется передача копии объектов в функции? Никак не используются преимущества С++ по эффективной работе с ссылками на объекты.
Мало того что это абсолютно неэффективно, так еще и во многих случаях может ломать код.

Например здесь сложно сказать, что произойдет после выхода из функции так как по факту объект str будет уничтожен сразу после выхода из функции.
Token* fromMisc(DOMString str)
{
MiscToken* misc = new MiscToken();
misc->data = str;
return (Token*)misc;
}
Token* fromText(DOMString str)
{
Text* text = new Text();
text->text = str;
return (Token*)text;
}

Это работает только потому-что у объекта DOMString нету деструктора! В итоге имеет на каждый чих копирование огромной строки и бесконечно большую утечку памяти.

Лучше наверное все таки использовать? (ну и конечно же написать нормальные деструкторы)
const DOMString& str
Честно говоря не знаю подробностей как они это реализовали, наверняка как нибудь ускоряют клиент игры. Я просто помню, что еще год назад они преподносили это как «фишку», и об этом уже писали и на хабре тоже (боты наиграли игр на 180 лет).

Все дело в том, что анализировать игры про игроков не имеет смысла, дота постоянно меняется, патчи выходят каждые две недели, они могут менять механики, скиллы персонажей, характеристики предметов, карту и вообще много чего. С учетом всего это актуальные «про»-игры это, ну скажем, игры за последний месяц. Их может быть не больше десятка-сотни. Боту в таком случае нечего анализировать.
Нет, данная сеть играет сама с собой тысячи матчей в день. Исследователи говорили, что в первых играх ИИ просто тыкался на месте и ничего не делал, позже ему начали подсказывать что делать и он начал предпринимать осмысленные действия, то есть он в день играет больше матчей чем вообще было матчей про игроков
У Dota есть API для ботов из коробки. Другое дело, что «банальных скриптов» не хватит, в Дота количество переменных на несколько порядков больше, чем в том же Го, но почему то в Го не могут обыграть профессионалов «банальным скриптом».
Не очень понятно о каких огромных усилиях вы говорите, но после пары лет игры в доту мне до сих пор абсолютно ничего не понятно, что происходит в ЛОЛ (на видео например). Где в Доте все понятно и логично, в Лоле абсолютный хаос и рандомная каша из спецэффектов.

IMHO восприятие визуального дизайна очень субъективно.
В таких языках любой «объект» на самом деле является указателем на соответсвующий объект. Копию нужно всегда делать явно.
1

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity