Pull to refresh

Comments 46

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


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


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

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

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

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

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

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

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

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

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


Foo

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

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


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

Вы имеете в виду что для перевода строки нужно также проверить на '\r'? Ну это небольшой оверхед.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here

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


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


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


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


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


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


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

UFO just landed and posted this here

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


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

UFO just landed and posted this here
Думать о параллелизме надо всегда [когда не map]

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


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


file
|> File.stream!([], @chunk)
|> Flow.from_enumerable()
|> Flow.partition()
|> Flow.reduce(fn -> @acc end, &parse/2)
|> Enum.to_list()
UFO just landed and posted this here

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

не хватает обработки других непробельных символов
UFO just landed and posted this here

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

UFO just landed and posted this here
Не хватает определения «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>-->
UFO just landed and posted this here

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

UFO just landed and posted this here

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

UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here

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

UFO just landed and posted this here
Sign up to leave a comment.

Articles

Change theme settings