Pull to refresh
16
0

Пользователь

Send message

Так сказать можно что угодно, свобода слова же. Главное не нарушать правил гитхаба, которые скорее всего достаточно жесткие, ну и законов тех стран где бываете. К языку то это какое имеет отношение?

На сколько я знаю, пользователями сейф апи раста надо давать больше гарантий. Т.е. например в си апи у вас условие на то что указатели валидны и всё, а остальное где то в доке. А если вы пишите апи для какого то языка с ГЦ то уже вы должны не только указатель валидный отдавать, а еще и счетчик ссылок правильно выставлять в зависимости от того что вы с этим указателем делаете. Аналогичная ситуация и с борроу чекером раста.

На одном Vec далеко не уедешь. Ну вот например можно посмотреть реализацию sort в стандартой либе там сплошной get_unchecked для индексов. Да в некоторых случаях можно обойтись zip/reduce/fold и т.д. Ну а что если самому надо написать что то такое? Насколько компилятор сможет выкинуть эти проверки если я буду писать safe? Почему если я докажу что мой ансейф алгоритм корректный это хуже чем если это доказали разрабы стд?
Ну или допустим в случае с актикс. Интересно какая структура данных была у автора, что ему понадобилось куда то сохранять мутабельные ссылки. Т.е. он пошел по пути "мамой клянусь" я создаю не больше одной. А как это формализовать? Борроу чекер не может, значит надо ансейф абстракцию. А достаточно ли вообще системы типов раст чтобы задекларировать сейф апи к такой абстракции?

Ну вообщем-то в переписке некий хрен сказал что автору актикс не надо писать на расте. Но сам этот хрен ничего нового технического до этого в обсуждение не внёс — только свое нытье. Собственно таких диванных экспертов миллионы по всему интернету и реалу. Жаль что автор так бомбанул.

Да основной юз-кейс numba для меня это использовать её для тех частей алгоритмов которые не ложатся легко на numpy. Но сейчас есть ещё xtensor для С++ который выглядит как питон и тоже легко интегрируется с массивами numpy через pybind11, пока не подвернулось случая опробовать.

Это из за small-string-optimization лишние операции?
Ну а если string_view. тогда должен быть просто char* + size_t, и не надо делать проверку где лежат данные.

Вы как буд-то первый кликбэйтный заголовок на хабре увидели.

закралась ошибка. исправил — стало быстрей.


Быстрый С++ Код
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <string>

size_t lev_dist(const std::string &s1, const std::string &s2) {
    const auto m = s1.size();
    const auto n = s2.size();

    std::vector<int> v0;
    v0.resize(n + 1);
        std::iota(v0.begin(), v0.end(), 0);
    auto v1 = v0;

    for (size_t i = 0; i < m; ++i) {
        v1[0] = i + 1;
        char c1 = s1[i];

        auto i0 = v0.cbegin();
        auto end = v0.cend() - 1;
        auto i1 = v1.begin();
        const char *c2 = s2.data();
        while (i0 != end) {
            int delInsCost = std::min(*(i0 + 1), *i1) + 1;
            int substCost = (c1 == *c2) ? *i0 : *i0 + 1;
            *(++i1) = std::min(delInsCost, substCost);
            ++i0;
            ++c2;
        }
        std::swap(v0, v1);
    }
    return v0[n];
}

int main()
{
    std::string s1(20000, 'a');
    std::string s2(20000, 'a');
    std::string s3(20000, 'b');

    std::cout << lev_dist(s1, s2) << std::endl;
    std::cout << lev_dist(s1, s3) << std::endl;
}

Дык тут на нем пишут пару интузиастов. Тут тригернул ты мало того что сишников так еще и шарпистов с жавистами которые заполонили все коменты :)

Печаль в том что мы идем к тому, что 90% людей не могут прочитать текст длиннее одного твита в твиттере (простите за тавтологию)

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

оставлю тут https://lkml.org/lkml/2018/6/5/769. тоже пытался понять после вашей дискуссии с "царём" в соседнем топике но ни**а не понял.

Cпасибо ссылку я нашёл но что с ней делать не знал.


Тогда откуда это строка в таблице? И не хотите ли вы ее как бы исправить?
C++ clang 9 323%
Это я так понимаю на Haswell цпу? На моем Skylake там где-то 200%. Далее путем минимального перемещения s1[i] за границу цикла, что есть в хаскель версии, все ожидаемо приходит в четкие 100%.
Более того хаскель у меня использовал дефалтный ллвм то беж llvm-8, т.е. на самом деле 100% у меня при clang-8, а 9ая версия может быстрее. В связи с этим вопрос какой ллвм используется у вас?

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

потом берем другие языки и пишем код одной рукой иногда надолго закрывая глаза

Первый позитивный комментарий

А можете дописать в хаскель листинг как должен выглядеть main и как запускать чтобы сравнить по простому?

Если интересно можно побенчить такую более олдскульную версию на указателях, у меня она на 15% быстрее с gcc и на 6% с clang9 (сама по себе шланг версия ускоряется в два раза после того как вынести s1[i] — вангую что из-за алиасинга компилятор не может сделать эту оптимизацию). Естественно это уже не самая наивная версия. Далее надо уже применять думаю некую векторизацию. И в рамках сравнение языков инетересно бы узнать как это будет выглядеть в разных языках.


код
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <string>

size_t lev_dist(const std::string& s1, const std::string& s2)
{
    const auto m = s1.size();
    const auto n = s2.size();

    std::vector<int> v0;
    v0.resize(n + 1, 0);

    std::vector<int> v1;
    v1.resize(n + 1, 0);

    for (size_t i = 0; i < m; ++i) {
        v1[0] = i + 1;
        char c1 = s1[i];

        auto i0 = v0.cbegin();
        auto end = v0.cend() - 1;               
        auto i1 = v1.begin();
        const char *c2 = s2.data();
        while (i0 != end) {
            int delInsCost = std::min(*(i0+1), *i1) + 1;
            int substCost = *i0 + !(c1 == *c2);
            *(++i1) = std::min(delInsCost, substCost);
            ++i0; ++c2;
        }
        std::swap(v0, v1);
    }
    return v0[n];
}

int main()
{
    std::string s1(20000, 'a');
    std::string s2(20000, 'a');
    std::string s3(20000, 'b');

    std::cout << lev_dist(s1, s2) << std::endl;
    std::cout << lev_dist(s1, s3) << std::endl;
}
ну да, ну да. Однако вангую, что сделано в большинстве реализаций по простому, как написано на стекеоверфлоу.

Абсолютно наоборот, стандартная библиотека делает все максимально быстро, насколько это позволяет ее обобщенность.


Да и собственно откройте код и узнайте, чем гадать.

Разницы нету, смотри тут https://godbolt.org/z/E5WRNT
В более общем случае может быть разница из-за порядка сравнений когда переменные приходят из разных мест но к "выделять память" отношения не имеет.

Information

Rating
5,071-st
Registered
Activity