Как стать автором
Обновить

Комментарии 46

А ничё, что предыдущие ораторы считали не только слова?


Это требование убивает правило 32х и заставляет учитывать предыдущий символ, что в арифметике добавляет заметное проседание.


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

Я отлично понимаю, что джентльменам принято верить на слово, но, может, поделитесь?

Зачитали файл в строку, вызвали сайз.

И это у вас изначально можно сделать за наносекунду? Вы уверены? А как меряли?

Ну, показывайте тогда python, можно даже не за нано-, а за микросекунду.
Очень интересно посмотреть будет.

Вызвать системную команду file, распарсить вывод, показать только размер.

Вы уверены, что это будет возможно сделать за микросекунду?
Можно таки увидеть пруф?

Во-первых, повторюсь, что я ни с кем не соревнуюсь (кроме как со своими предыдущими реализациями).
Во-вторых, не очень понял суть Вашей претензии. Я посчитал слова/строки/байты, вроде бы это все, разве нет? И что значит я не учитываю предыдущий символ?
На счет <= ' ' — да, скрупулезная проверка на пробелы посложнее с точки зрения арифметики. Если будет возможность — может быть реализую и ее.

Скормите вашей реализации вот это:


Foo

        Bar
Words: 2; lines: 3; chars: 18
Elapsed time: 0.000200ms
ЧЯДНТ?

Тут не так парсер хабра, но я понял ваши аргументы, и даже согласен с ними.


Строк так, правда, в любом случае — 4.

Вы имеете в виду что для перевода строки нужно также проверить на '\r'? Ну это небольшой оверхед.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Ох. Как на перемену из третьего класса вышел, прям.


Я не уверен, я думаю, что в 2020 все компиляторы в натив сделают примерно одинаково.


Все виртуальные машины сделают чуть хуже, но не сильно.


Всех, кто так не сможет, надо на свалку.


И забавно, что на моей рабочей машине, с 32 ядрами, и идиоматичный си, и идиоматичный хаскель, влетают идиоматичному эрлангу на почти порядок.


Потому что в 2020 тут рулит идиоматичность распараллеливания, а не опций компилятора.


Убираю линейку с видом победителя, иду на урок.

НЛО прилетело и опубликовало эту надпись здесь

Поделить файл — это как? Мне мать писала, что хаскель ленив до жути.


И в языке, аоторый из коробки готов к распараллеливанию, об этом думать не надо. Я именно об этом.

НЛО прилетело и опубликовало эту надпись здесь
Думать о параллелизме надо всегда [когда не map]

И да, и нет. Да — в смысле, нужно понять, когда эмитнуть синхронизацию (в совсем запутанных случаях). Нет — в смысле вот такого кошмара, как выше, в клиентском коде быть не должно.


Сравните с кодом из моего гиста:


file
|> File.stream!([], @chunk)
|> Flow.from_enumerable()
|> Flow.partition()
|> Flow.reduce(fn -> @acc end, &parse/2)
|> Enum.to_list()
НЛО прилетело и опубликовало эту надпись здесь

А, ну это-то конечно, но тут чуда никто и не ждал.

На 28-29 примерно :)

FSM в наивной реализации будет в разы медленнее показанной наивной реализации на C. Но если продолжить вашу мысль в верном направлении, то получится что-то подобное.

не хватает обработки других непробельных символов
НЛО прилетело и опубликовало эту надпись здесь

Если не затруднит, то прогоните пожалуйста на вашей машине вариант с развернутым циклом (т.е. с заменой этого цикла на код под спойлером). Хочется нащупать отличие кода из-под ghc от C.

НЛО прилетело и опубликовало эту надпись здесь
Не хватает определения «wc» в самом начале статьи для тех, кто не в теме
судя из текста это word count. Но действительно, для непосвященного звучит двояко
Я прошу прощения, но как у вас обработается символ с кодом 160? Как пробел?
  1. Для полноты картины в статье конечно не хватает отсылки к не-наивной переносимой реализации (aka "С" наносит ответный удар"), в том числе замера её скорости на вашей машине. На всякий — popcount/Hamming_weight в там нет намеренно ради переносимости.
  2. О том что производительность "на SIMDах" будет в пределах memory bandwidth было заявлено примерно сразу. Тем не менее, соглашусь что многим это не очевидно и лучше "показать на пальцах".
  3. Вы еще раз поменяли условия/требования (выбросили табуляции и т.п.), чем еще больше понизили градус смысла в этом флешмобе бенчмарков.
    В контрольных цифрах должно быть lines 15000000, words 44774631, chars 1871822210.
  4. Другой CPU, другой компилятор, другая ОС. Поэтому недостаёт результатов работы других реализаций в ваших условиях.
  5. По информации 0xd34df00d Хаскель быстрее наивной С-реализации (я имею в виду комментарий "Но ведь не обходит. 2 секунды для С против 1.45 для хаскеля"). Если я правильно понимаю, причина в достаточно простой "механике": ghc (хаскель-компилятор) немного раскатывает вот этот цикл (aka loop unrolling). Точнее говоря, не раскатывает, а не полностью сворачивает (aka fold), и такой цикл отрабатывает быстрее. Предлагаю всем самостоятельно оценить насколько это определяющий критерий победы, с учетом того что clang с -march=native заставляет наивный код работать быстрее хаскеля.
    В моём понимании C-цикл под спойлером должен работать "со скоростью хаскеля". Хорошо-бы кто-то проверил (достаточно вставить этот кусок в код по первой ссылке и сравнить скорость с Хаскель-реализацией на одной машине).

Заголовок спойлера
for (size_t i = 0; i < bytes; i += 8) {
    unsigned char c0 = text[i];
    unsigned char c1 = text[i+1];
    unsigned char c2 = text[i+2];
    unsigned char c3 = text[i+3];
    unsigned char c4 = text[i+4];
    unsigned char c5 = text[i+5];
    unsigned char c6 = text[i+6];
    unsigned char c7 = text[i+7];

    result.lines += c0 == '\n';
    result.lines += c1 == '\n';
    result.lines += c2 == '\n';
    result.lines += c3 == '\n';
    result.lines += c4 == '\n';
    result.lines += c5 == '\n';
    result.lines += c6 == '\n';
    result.lines += c7 == '\n';

    _Bool x0 = (c0 != ' ') && (c0 - 9 > 4);
    _Bool x1 = (c1 != ' ') && (c1 - 9 > 4);
    _Bool x2 = (c2 != ' ') && (c2 - 9 > 4);
    _Bool x3 = (c3 != ' ') && (c3 - 9 > 4);
    _Bool x4 = (c4 != ' ') && (c4 - 9 > 4);
    _Bool x5 = (c5 != ' ') && (c5 - 9 > 4);
    _Bool x6 = (c6 != ' ') && (c6 - 9 > 4);
    _Bool x7 = (c7 != ' ') && (c7 - 9 > 4);

    result.words += x0 && !prev;
    result.words += x1 && !x0;
    result.words += x2 && !x1;
    result.words += x3 && !x2;
    result.words += x4 && !x3;
    result.words += x5 && !x4;
    result.words += x6 && !x5;
    result.words += x7 && !x6;
    prev = x7;
  }~~~

<!--</spoiler>-->
НЛО прилетело и опубликовало эту надпись здесь

А ghc (вроде-бы) умеет в Cкомпилировать? Весьма вероятно этого будет достаточно.

НЛО прилетело и опубликовало эту надпись здесь

Кстати, ассемблерный вывод ghc совсем сухой, без его "технических" комментариев?
Может какой-нибудь ключик есть для аннотации?
Должны быть какие-то средства навигации или "дорожные столбы", чтобы сами разработчики ghc поманили что из чего получилось.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Ну и тут мы только слова считаем, арифметики сильно меньше, чем в корректном решении.

НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории