• Python как компилируемый статически типизированный язык программирования
    0
    Пара слов про pybind11. Если вы глянете на исходники pybind11, то станет понятно, что это во многом синтаксический сахар над тем самым исходным core C API. И то, что pybind11 стал таким простым, этот как раз заслуга исходной хорошо продуманной интеграции C. Да и в целом, на Python есть биндинги почти к любой библиотеке на C/C++/Fortran. Вряд ли это было бы возможно при плохо продуманной интеграции.

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

    По поводу Python есть ряд мифов, в том числе о его низкой производительности. Я лишь хочу показать, что современный Python имеет большое количество способов практически полность преодолеть проблему низкой производительности.

    А что касается более мощных языков. Мне они крайне интересны. Но все, что я хочу, чтобы люди не совершали ошибок, при которых мы переписали всё на $КРУТОЙЯЗЫК, но стартап всё равно не взлетел.
  • Python как компилируемый статически типизированный язык программирования
    +3
    Вот тут не соглашусь. По большому счету, весь современный Machine Learning это TensorFlow + PyTorch. А это все Python.

    Более того, уже огромное количество казалось бы несвязанных с machine learning задач начинают решать при помощи тех же фреймвоков, например те же обыкновенные дифференциальные уравнения.

    А связано это с тем фактом, что современное hardware для научных вычислений довольно таки гетерогенное: многоядерные CPU, кластеры машин, GPU, TPU. Вручную параллелить алгоритмы на весь этот зоопарк слишком тяжело.

    И несколько лет назад акцент в научных вычислениях сместился к идеологии потоковых вычислительных графов. Лучше всего это описано в документации к TensorFlow. Каждый алгоритм мы представляем в виде графа вычислений. Каждый узел графа это какая-то операция, дифференцирование, интегрирование, свертка и т.п. Далее этот граф компилируется под каждое специализированное hardwarе, и через него пропускается сплошной поток данных.

    Оказалось, что большое количество вычислительных задач крайне эффективно вписывается в эту схему. А язык Python оказался идеальным для создания таких графов.
  • Python как компилируемый статически типизированный язык программирования
    –1
    Для линейной алгебры никто питоновские массивы не использует, так что наличие слайсов в языке погоды не меняет, библиотеки все решают.
    Встроенные слайсы, оператор '@' для матричного умножения и много всего другого. Поглядите на сравнение одинаковых операций Python c MatLab. Python гораздо красивее выглядит чем Matlab. А MatLab специально создавался для научных вычислений с матрицами. Понятно, что все делается через библиотеки. Но оцените, как органично эти библиотеки вписываются в сам язык!

    Идеальное взаимодействие с СИ?! приходится всё руками делать, поддержка плюсов вообще сомневаюсь что есть, слишком уж это сложная проблема
    А вы пробовали pybind11. Я уже и не знаю, что проще то может быть, пара строчек и получем бесшовную интеграцию C++ кода в Python:
    #include <pybind11/pybind11.h>
    
    int add(int i, int j) {
        return i + j;
    }
    
    PYBIND11_MODULE(example, m) {
        m.doc() = "pybind11 example plugin"; // optional module docstring
    
        m.def("add", &add, "A function which adds two numbers");
    }
    
  • Python как компилируемый статически типизированный язык программирования
    +1
    Если рассматривать просто как язык, то ничем не лучше, а местами так-то и хуже, а где-то и вообще плохо.

    А вот если рассматривать в контексте решения практических задач, особено связанных с научными вычислениями, то мы ликвидировали существенный провал в производительности. При этом вполне элегантно, красиво и с учетом дзен Python. Код остался таким же легким для чтения и для понимания.

    Теперь можно построить буквально парой строчек + парой аннотаций крайне производительный код, который перемолет огромные массивы данных крайне быстро, почти на 100% эффективно используя доступные ресурсы.
  • Python как компилируемый статически типизированный язык программирования
    0
    Ну да, это можно назвать путем костылей. А еще можно назвать естественной эволюцией наиболее приспособленного к реальным нуждам инструмента. Так то у нас тоже есть не один баг в дизайне. Однако как то живем, вполне успешно при этом.

    Может быть Python и создавался как один из простейших скриптовых языков. Но с рождения он получил очень много преимуществ: a) крайне понятный для чтения язык, б) в целом почти естественная поддержка массивов со слайсами, что идеально вписалось в научные вычисления, основанные на линейной алгебре, c) идеальное взаимодействие с Fortran/C/C++, d) внятная система пакетов.

    В результате Python стали «идеальным клеем» для связи между численными библиотеками, позволяя их вызывать почти без оверхеда. Это позволило стать Python почти идеальным языком для вычислений, основанных на концепции потокового графа, как в Tensorflow. А это позволило для ряда задач почти решить проблему гетерогенных вычислительных систем (CPU + GPU) с автоматической параллелизацией.

    Но пока в Python еще оставался один зазор. Если код не вписывался в NumPy векторизацию, или построить граф потоковых вычислений было слишком накладно, приходилось это код выполнять на медленном интерпретаторе.

    И вот теперь этот зазор почти ликвидирован. Мы получили аннотацию типов и эффективную JIT комплицию. И это все вместе выглядит вполне себе красиво, почти идеально вписалось в идеологию Python.
  • Python как компилируемый статически типизированный язык программирования
    +1
    Так-то это вообще-то не статья, а новость о выходе новой версии Numba 0.52.0 с ключевой особенностью о поддержке аннотаций типов.
  • Python как компилируемый статически типизированный язык программирования
    +1
    Так то оно все может быть и верно. Но быстрый и параллельный код писать хочется. А быстрый код без типов довольно сложно получить.

    То, что я вижу в Numba, вполне в духе дзена Python и позволяет получить производительность, близкую к нативной. По крайней мере Numba c типами гораздо ближе к красивому Python, чем те же расширения на монструозном Cython.

    У Python нет цели стать системным языком типа Rust. Но вот писать быструю математику на высоком уровне на Python очень удобно. Собственно это и подчеркивает его популярность в мире. Сейчас в экосистеме Python появляются очень хорошие инструменты, позволяющие элегантным образом снять его проблемы с производительностью. Меня это не может не радовать.
  • Python как компилируемый статически типизированный язык программирования
    0
    _del_
  • Python как компилируемый статически типизированный язык программирования
    +1
    JIT код крайне эффективен, в основе тот же современный LLVM компилятор. Но я бы пока все-таки не советовал переписывать полностью код Python в этом стиле. Это лишает Python его преимуществ высокоуровневого динамического языка.

    Эффективно это работает следующим образом. Выделяются критические к производительности участки кода, разнородные численные данные преобразаются к NumPy массивам, а далее расставляются типы и все JIT-компилируется.

    По сравнению с классическим подходом на чистом NumPy этот подход очень близок по производительности к нативному коду, так как: a) убирается overhead между вызовами NumPy, b) можно использовать более разнообразные структуры данных (вложенные классы с простыми типами), с) можно использовать классические вложенные циклы, что иногда более гибко чем NumPy векторизация.

    При правильном проектировании и если использовать с самого начала аннотации типов все сводится только к расстановке jit в паре мест.
  • Python как компилируемый статически типизированный язык программирования
    0
    Да, все верно, последняя версия 0.52.0. Спасибо, поправил в новости.
  • О шахматах. И не только
    0
    Можно еще вот тут посмотреть эту позицию.

    Это альтернативная открытая база 7-фигурок, но тут главная метрика DTZ вместо DTM.
  • О шахматах. И не только
    0
    Насколько я помню, впервые это правило отменили для мата двумя конями. Вообще считается, что мат двумя конями невозможен. Но (!) если добавить слабейшей стороне пешку, вроде как усиливая ее, мат становится возможен. Но далеко за пределами 50 ходов.

    На этой позиции у сильнейшей стороны два коня. Результат ничья.

    Но мы добавляем слабейшей стороне пешку. И получаем мат в 138 (!) ходов. Непостижимо для человека. Всего три фигуры. Но результат мат. При этом белые очень аккуратно обходят эту пешку. А черный король бродит по всей доске.
  • О шахматах. И не только
    +6
    У меня тут есть несколько соображений.

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

    2. В очень многих ситуациях человек просто не может постичь всю глубину шахмат. Вот простейшие примеры из 7-фигурной базы. Не считая королей, всего 5 фигур. Но мат достигается только 545 единственными ходами!

    3. А игра уже меняется. Если лет десять назад считалось, что необходимо получить преимущество в дебюте, то сейчас ведущие гроссмейстеры идут на просто игровые позиции. И очень много компьютерных приемов я уже замечаю, например задвижение крайних пешек.
  • О шахматах. И не только
    +5
    С момента AlphaZero в компьютерных шахматах появилось много интересных вещей.

    1. Во первых это Leela Chess. Это открытая реализация нейросетевого подхода AlphaZero, активно развивающаяся, с большим количеством вариантов сетей.

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

    2. Но совсем недавно появилась новая архитектура нейронной сети, работающая только на CPU. Она называется NNUE. Она позволяет улучшить alpha-beta отсечение с использованием нейросетевой оценки. Она работает только на CPU, так как копировать данные между CPU и GPU слишком накладно. Судя по последним данным, такой гибридный подход радикально усилил силу игры, почти на 100 ELO NNUE evaluation, что для текущих компьютерных шахмат серьезный прорыв.

    Вот такая гибридная арихектура на CPU пока самая сильная на данный момент времени.

    Вот график прироста ELO с использованием NNUE

    image
  • Выход стабильной версии Python 3.9.0
    +2
    Я бы еще добавил, что Python перешел на стабильные годовые циклы выпуска, см. PEP 602.

    Каждая новая версия Python теперь будет выходить в октябре. Python 3.10 выйдет в октябре 2021, Python 3.11 в октябре 2022. А каждые два месяца будет выходить бакфикс. Для меня это великолепная новость, теперь можно четко планировать upgrade python окружения.
  • Julia готова для прода
    +1
    Огромное спасибо, погляжу! Я уже давно пытаюсь свалить с Питона куда-нибудь. Я научился писать быстрые программы на Python, с использованием cython, numpy, numba, jax, с-модули, etc… Но, честно говоря, хочется уже не зоопарка, а единой кодовой базы.

    Julia выглядит как идеальный вариант, но пока мелкие шероховатости раздражают. Я пару раз пытался плотно пересесть на Julia, начиная с мелких скриптов. Но, то медленный старт немного достает, то недостаточная стабильность. Многие пакеты, активно развивающиеся год назад, сейчас почти заморожены. Мало хорошей документации, а GitHub копаться не всегда есть время.

    Еще немного смущает порой агрессивный маркетинг и смущает попытка ранней коммерциализации Julia, т.е. Julia Computing предлагает Enterprise вариант для тех, кому нужна хорошая поддержка. Я бы наоборот, больший упор делал на честную работу с community. С горя я уже к фортрану начал присматриваться.

    Очень надеюсь, что Julia постепенно наберет базу пользователей, развитое коммьюнити и стабилизирует все пакеты. Идея языка и сам подход мне очень нравятся!
  • Julia готова для прода
    +2
    Кстати, я недавно глянул на современный фортран. Я то думал, что это какой-то древний артефакт. Но оказалось это современный, активно развивающийся, предельно ясный язык, быстрый и параллельный.

    Я вот подумываю, когда тормоза Питона меня окончательно достанут, писать модули на фортране.
  • Julia готова для прода
    +2
    Те, кто работает плотно с Julia, подскажите, ее уже можно использовать в небольших standalone скриптах?

    Я год назад пробовал написать небольшой standalone скрипт, который запускается по таймеру, собирает из API json'ы, делает расчет, пишет в файл и завершает работу.

    К моему удивлению этот скрипт работал каждый раз секунд около 20, тогда как «медленный» python работал какие-то миллисекунды. Я написал в форумы, мне посоветовали запускать мой код из REPL, который все время висит в памяти. Я тогда немного удивился и забил на julia.

    Подскажите, сейчас это починили?
  • Новые фичи в Python 3.9
    +1
    Я бы попробовал это реализовать двумя путями.

    Если оставаться чисто в парадигме вложенных классов, я бы это сделал через @jitclass, как в jitclass.py и в binarytree.py.

    Другой вариант вместо python классов использовать Numpy Strutured Array и их поддержку в Numba, structures.py.
  • Новые фичи в Python 3.9
    +1
    Пока не могут, так как эти аннотации пришли в python из необходимости существенно ускорить математические вычисления, основанные на numpy array. Не все типы python пока еще поддерживаются. Да и тайпхинты пока все еще в процессе развития.

    Но в ближайших планах как раз и перейти на тайпхинты с поддержкой все большего количество чистых пайтоновских структур данных.
  • Новые фичи в Python 3.9
    +2
    С одной стороны вы правы. Под капотом все тоже компилирование в нейтив. Но, с точки зрения программиста, ситуация меняется. Если раньше нужно было писать брутальный C модуль или использовать cython с его несколько извращенным синтаксисом, то теперь с numba достаточно подключения библиотеки и аннотации типов. И формально программист не выходит за пределы логики python.

    И я вижу, как это дальше развивается. Numba тесно интегрируется с аннотацией типов python и поддерживает все больше и больше чистых python структур, а не только numpy array. Все те функции python, для которых возможно полное выведение типов, будут скомпилированы в native и свободны от GIL, при этом будут бесшовно сшиваться с python интерпретаторами.

    Это похоже на концепцию языка julia, где авторы создали динамический язык, способный к автоматическому выведению типов. Правда в julia они начали с того, что обрезали все те возможности языка, для которых такое выведение типов невозможно.

    Python идет примерно по той же дороге, выделяя то подмножество языка, для которого это возможно, и шаг за шагом расширяет это подмножество.
  • Новые фичи в Python 3.9
    +2
    Да, там 0.047. Спасибо за правку!
  • Новые фичи в Python 3.9
    +23
    Допустим у нас в python интерпретаторе есть python функция, для которой мы знаем
    1. Типы и структуру входных и выходных параметров.
    2. Типы переменных в самой функции строго зависят от входных параметров или являются элементарными типами.

    Тогда для такой функции мы можем выйти из python интепретатора, освободить GIL, скомпилировать код в нэйтив для данной платформы, выполнить его и вернуться обратно в интепретатор. Самый удобный пакет сейчас для такого это numba, которая основана на LLVM.

    Самое главное, что вся эта внутренняя работа абослютно незаметна для программиста. Все что нужно, это просто расставить типы. Уже как несколько лет такой подход идеально работает для математических вычислений в python, основанных на numpy array. Сам numpy array представляет собой python обертку над линейными областями памяти, поэтому для таких данных код генерируется очень хороший.

    Для примера, рассмотрим следующую задачу.

    Постановка задачи
    Даны два набора из N точек в трехмерном пространстве. Необходимо посчитать матрицу попарных регуляризированных обратных расстояний. В нашем пример N = 5000.

    def main():
        """ For the given points set calculate RBF matrix
        base on regularized inverse distances.
        
        Input data:
        -----------
        
        p = [[p0_x, p0_y, p0_y],
             [p0_x, p0_y, p0_y],
             ...
             [pN_x, pN_y, pN_y]]
        
        q = [[q0_x, q1_x, ..., qN_x],
             [q0_y, q1_x, ..., qN_x],
             [q0_z, q1_z, ..., qN_z]]
             
        Output data:
        -----------
        
        R = [[f(p0, q0), f(p0, q1), ..., f(p0, qN)],
             [f(p1, q0), f(p1, q1), ..., f(p1, qN)],
             ...
             [f(pN, q0), f(pN, q1), ..., f(pN, qN)]],
        where f(p, q) = 1 / (1 + |q - p|)
        """
    
        N = 5000
    
        p = np.random.rand(N, 3)
        q = np.random.rand(3, N)
    


    Чистый код на Python
    def get_R_py(p, q):
        R = np.empty((p.shape[0], q.shape[1]))
    
        for i in range(p.shape[0]):
            for j in range(q.shape[1]):
                rx = p[i, 0] - q[0, j]
                ry = p[i, 1] - q[1, j]
                rz = p[i, 2] - q[2, j]
                R[i, j] = 1 / (1 + math.sqrt(rx * rx + ry * ry + rz * rz))
    
        return R
    


    Время работы: 100.479 c.

    Это очень долго. Теперь начинается магия!

    Последовательная реализация с аннотацией типов
    from numba import float64, jit
    
    @jit(float64[:, :](float64[:, :], float64[:, :]), nopython=True, nogil=True)
    def get_R_numba_sp(p, q):
        R = np.empty((p.shape[0], q.shape[1]))
    
        for i in range(p.shape[0]):
            for j in range(q.shape[1]):
                rx = p[i, 0] - q[0, j]
                ry = p[i, 1] - q[1, j]
                rz = p[i, 2] - q[2, j]
                R[i, j] = 1 / (1 + math.sqrt(rx * rx + ry * ry + rz * rz))
    
        return R
    

    Время работы: 0.154 с, ускорее примерно в 700 раз. И все, что мы для этого сделали, по большому счету, только проставили типы.

    Параллельная реализация с аннотацией типов
    Ну ладно, а как на счет параллельности и GIL? Почти без изменений:

    @jit(float64[:, :](float64[:, :], float64[:, :]), nopython=True, nogil=True, parallel=True)
    def get_R_numba_mp(p, q):
        R = np.empty((p.shape[0], q.shape[1]))
    
        for i in prange(p.shape[0]):
            for j in range(q.shape[1]):
                rx = p[i, 0] - q[0, j]
                ry = p[i, 1] - q[1, j]
                rz = p[i, 2] - q[2, j]
    
                R[i, j] = 1 / (1 + math.sqrt(rx * rx + ry * ry + rz * rz))
    
        return R
    

    Мы добавили а) parallel=True в аннотацию и б) во внешнем цикле range заменили на prange.

    Время работы: 0.47 с, ускорение по сравнения с последовательной версией примерно в 3.3 раза, что неплохо для моего четырехядерного лаптопа.

    И что дальше?
    Уже как несколько лет это работает идеально для математики и numpy array. Но разработчики numba пошли гораздо дальше. Очень важный момент, что такой же аннотацией типов код можно скомплировать и для GPU. Кроме того, стали поддерживаться почти все python типы, включая типизированные List, Dict, а также спецификации для классов, что я показывал выше. А в планах тесная интеграция с python type annotations.

    Сейчас репозиторий на GitHub очень активный, около 170 контрибьюторов. И мне нравится, как развивается этот проект.
  • Новые фичи в Python 3.9
    0
    Сейчас Python очень активно развивается, большей частью в сторону решения своих главных проблем с производительностью и GIL. Например, уже сейчас стало очень просто расставить типизацию в ключевых местах и получить компилированый код, свободный от GIL:

    from numba import int32, deferred_type, optional
    from numba.experimental import jitclass
    
    node_type = deferred_type()
    
    spec = OrderedDict()
    spec['data'] = int32
    spec['next'] = optional(node_type)
    
    @jitclass(spec)
    class LinkedNode(object):
        def __init__(self, data, next):
            self.data = data
            self.next = next
    
        def prepend(self, data):
            return LinkedNode(data, self)
    
    node_type.define(LinkedNode.class_type.instance_type)
    

    С учетом активно развивающейся концепции аннотации типов и усовершенствованием парсера синтаксиса, мы скором получим динамический язык, который путем расстановки типов в ключевых местах (и их автоматического вывода) можно ускорить практически до скорости языка C.
  • Почему будущее не за Python
    +2
    И еще раз о скорости Python. Не так давно тут была статья с хорошим бенчмарком на многих языках программирования.

    Так вот, Python с jit компиляцией по скорости был на уровне C, Go и Rust. Поэтому миф о медленном Python давно уже пора забыть. Правда тут в другом.

    На Python можно писать медленно, но в 2020 году нет никаких проблем оптимизировать критические участки кода парой аннотаций для jit комплиции.

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

    Поэтому с точки зрения скорости разработки и производительности конечного года Python сейчас во многом уникальный инструмент.

    Не говоря о том, что почти любая научная C/Fortran библиотека имеет обвязку на Python. И как дополнительный бонус крайне удобные Python ноутбуки и вменяемая система управления пакетами.
  • Почему будущее не за Python
    +1
    Проблемы скорости и параллельного выполнения давного уже решаются jit компиляцией. Вот простейший пример:
    @numba.jit(nopython=True, parallel=True)
    def logistic_regression(Y, X, w, iterations):
        for i in range(iterations):
            w -= np.dot(((1.0 /
                  (1.0 + np.exp(-Y * np.dot(X, w)))
                  - 1.0) * Y), X)
        return w
    
  • А что, если без Python? Julia для машинного обучения и вообще
    +1
    Тут «вычисления» как-то слишком широко получились. Численного анализа в питоне почти нет, если сравнивать с джулией.
    Ну как сказать… Вот, например, потрясающая библотека на Python quadpy, где собраны более 1500 методов численного интегрирования. Пока такого в Julia я не встречал. Или библиотека cvxopt, одна из важнейших библиотек для решения задач Конвексной оптимизации. Интересно, что реализация на Julia вызывает реализацию на Python через PyCall.
    В питоне автоматом тоже ничего не работает, там надо или njit расставлять, или векторизовать, или типы прописыать.
    Ну в питоне то к этому все готовы изначально. А вот Julia позиционируется двусмысленно. С одной стороны типы необязательны. Но если вы хотите быстрый код, но нужно писать уже по другому. Сделали бы тогда типы обязательными.
  • А что, если без Python? Julia для машинного обучения и вообще
    –2
    Для математиков это скорее Wolfram Mathematica, Maple или на крайний случай Matlab. A в Julia математик может много всего странного написать.

    В этом то и проблема Julia, на мой взгляд. Для математиков она не так проста, как позиционируется. А инженеры предпочитают более выразительные инструменты.
  • А что, если без Python? Julia для машинного обучения и вообще
    +1
    Если я понял правильно, то по идеологии «Julia» это тоже самое что и «Python + Numba», только язык более современный. Но стиль разработки научного кода не слишком то и различается. Мы сначала пишем прототип, а если нужна производительность расставляем типы, что позволяет выполнить эффективную JIT компиляцию.

    Но вот тут то и кроется проблема для широкого применения языка. Если от Python сразу ожидают медленной скорости и знают приемы как ее преодолеть, то от Julia сразу ожидают высокой производительности. А это не всегда работает. Например вот в этой статье habr.com/ru/post/483864 реализация Python + Numba была в два раза быстрее реализации от Julia.

    Таким образом мы имеем Python мир, в котором собрано уже все, что может быть в мире вычислений. Да и проблемы с производительностью уже в прошлом, по большому счету.

    С другой стороны есть развивающийся мир Julia, в котором все вроде бы более красиво и чисто. Но… Автоматом все-равно быстро то не работает, нужно также думать как оптимизировать код. Да и библиотек маловато.

    В результате под данным TIOBE Julia за 2019 год опустилась в рейтинге языков с #37 до #47 места, что грустно.
  • Быстрее, чем C++; медленнее, чем PHP
    +1
    Выше уже ответили, нужны только numpy и numba:
    $ pip3 install numpy
    $ pip3 install numba


    На всякий случай, вот полный код:
    #!/usr/bin/env python3
    import sys
    import time
    import numpy as np
    from numba import jit
    
    
    @jit
    def lev_dist(s1: bytes, s2: bytes) -> int:
        m = len(s1)
        n = len(s2)
    
        # Edge cases.
        if m == 0:
            return n
        elif n == 0:
            return m
    
        v0 = np.arange(0, n + 1)
        v1 = np.arange(0, n + 1)
    
        for i, c1 in enumerate(s1):
            v1[0] = i + 1
    
            for j, c2 in enumerate(s2):
                subst_cost = v0[j] if c1 == c2 else (v0[j] + 1)
                del_cost = v0[j + 1] + 1
                ins_cost = v1[j] + 1
    
                # min(subst_cost, del_cost, ins_cost) is slow.
                min_cost = subst_cost if subst_cost < del_cost else del_cost
                if ins_cost < min_cost:
                    min_cost = ins_cost
                v1[j + 1] = min_cost
    
            v0, v1 = v1, v0
    
        return v0[n]
    
    
    if __name__ == "__main__":
        s1 = b"a" * 15_000
        s2 = s1
        s3 = b"b" * 15_000
    
        exec_time = -time.monotonic()
    
        print(lev_dist(s1, s2))
        print(lev_dist(s1, s3))
    
        exec_time += time.monotonic()
        print(f"Finished in {exec_time:.3f}s", file=sys.stderr)
    
  • Быстрее, чем C++; медленнее, чем PHP
    +1
    Тут вопрос сложный. У нас есть Java Script с его V8, nim с его компиляцией в C, Julia с ее компиляцией через llvm. Да и тот же pypy в несколько раз медленнее numba, хотя оба пытаются компилировать код.

    На мой взгляд вполне честно все сравнивать с точки зрения разработчика. Есть код, есть плафторма, есть результат.

    Да и чем, грубо говоря, декоратор "@jit" так уж сильно отличается от набора специальных флагов «gcc» с подсказками для оптимизаций?
  • Быстрее, чем C++; медленнее, чем PHP
    +2
    Можно привести и к 20 тыщ, но в целом видно, что C и Python практически сравнимы по скорости.
    Ну и, кстати, сколько тогда работы выполняется в питоне, а сколько — в C?
    Ну Python же это язык. У него может быть реализация как у интепретируемого языка, а может быть и jit компиляция.

    А по факту я взял приведенный исходник на Python, практически добавил всего одну аннотацию, запустил в стандартной реализации CPython и получил практически скорость языка С. С точки зрения разработчика я нигде не вышел из окружения Python.
  • Быстрее, чем C++; медленнее, чем PHP
    +4
    Про то, что Python не готов для вычислений, вы не правы. И PyPy не нужен, нужны только Numpy, Numba и самый обычный Python. Вот результаты

    C
    Windows 10, gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
    $ gcc ld.c -Ofast -fPIC -fPIE -static -flto -o ld.exe
    $ ld.exe
    0
    15000
    Finished in 0.934s

    Python
    Косметические изменения в коде:
    import sys
    import time
    import numpy as np
    from numba import jit
    
    
    @jit
    def lev_dist(s1: bytes, s2: bytes) -> int:
        m = len(s1)
        n = len(s2)
    
        # Edge cases.
        if m == 0:
            return n
        elif n == 0:
            return m
    
        v0 = np.arange(0, n + 1)
        v1 = np.arange(0, n + 1)
    
        for i, c1 in enumerate(s1):
            v1[0] = i + 1
    
            for j, c2 in enumerate(s2):
                subst_cost = v0[j] if c1 == c2 else (v0[j] + 1)
                del_cost = v0[j + 1] + 1
                ins_cost = v1[j] + 1
    
                # min(subst_cost, del_cost, ins_cost) is slow.
                min_cost = subst_cost if subst_cost < del_cost else del_cost
                if ins_cost < min_cost:
                    min_cost = ins_cost
                v1[j + 1] = min_cost
    
            v0, v1 = v1, v0
    
        return v0[n]
    


    Результаты на Windows 10, Python 3.7.5
    $ python ld.py
    0
    15000
    Finished in 0.968s

    На долю процентов C быстрее, но скорости практически сравнимы.
  • Julia. С чего начать проект?…
    +1
    Я вижу, что тут используется дистрибутив Anaconda. Большая часть таких ошибок лечится одной командой anaconda package manager:
    $ conda install libgcc
    
  • Julia. С чего начать проект?…
    +1
    Использовать то можно, конечно. Но дело не в гипотетической возможности использования, а в чистоте и продуктивности решения.

    Python это «официальный» API для Tensorflow. По статистике на github.com/tensorflow/tensorflow Python составляет более 30% кодовой базы, что для совсем тонкого интерфейса многовато. Да и вообще использование low-level C/C++ модулей распространенное решение в экосистеме Python, это делается очень просто и органично. Python тут выступает очень эффективным «клеем» для интеграции low-level функций.

    Для экосистемы Julia использование C/С++ модулей не слишком «спортивно». Julia позиционируется как язык, способный конкурировать с C/C++ на его поле за счет развитой системы типов с диспетчеризацией вызовов и JIT компиляции. Иделогия Julia как раз в том, чтобы иметь на высоком уровне выразительный язык типа MatLab для научных вычислений, но при этом иметь возможность получать произодительность нативной плафтормы. Поэтому оборачивание C/C++ TensorFlow в Julia выглядит как пренебрежение идеологией Julia.
  • Julia. С чего начать проект?…
    +2
    Спасибо за ссылки! Да, это все интересные иницативы. Посмотрим, как оно все будет развиваться. В любом случае я рад, что область научных вычислений сейчас активно идет вперед.
  • Julia. С чего начать проект?…
    +1
    Есть github.com/JuliaLang/PackageCompiler.jl
    Можно сгенерировать запускаемый бинарник. Только код должен быть оформлен в пакет и быть установлен как пакет. А бинарник будет довольно жирным.
    Да, я его как раз и пробовал. Но для меня пока и процесс компиляции, и результат оказались довольно тяжеловесными. Надеюсь, что компилятор будет постепенно совершенствоваться.
    Нам удавалось избегать использования Питона где бы то ни было. И, как раз сейчас, я сомневаюсь в его будущем и целесообразности каких-либо инвестиций в него.
    Хмм… Ну не знаю. Пока я наблюдаю как раз обратную картину взрывного роста использования Питона в научных расчетах. Почти каждая крупная компания недавно выдвинула свою инициативу развития Python. Вот некоторые примеры
    — Intel: software.intel.com/distribution-for-python, полная интеграция со своими флагманскими библиотеками для высокопроизводительных расчетов Intel Math Kernel Library, Intel Data Analytics Acceleration Library
    — NVidia: developer.nvidia.com/how-to-cuda-python, полная поддержка компиляции Python для GPU
    — Google: это TensorFlow, сейчас один из важнейших продуктов для Google,
    — Netflix: практически полностью построен на Python, medium.com/netflix-techblog/python-at-netflix-bba45dae649e, тут как раз и преимущество Python, что на нем можно писать не только научные расчеты, а строить всю инфраструктуру
    — одно из главных открытий в физике последних лет, непосредственно измеренные гравитационные волны, были рассчитаны на Python: pycbc.org,
    — много много других

    Вот еще интересная публикация о статистике использования фреймворков для машинного обучения, собранная по данным упоминания на самых популярных научных конференциях: thegradient.pub/state-of-ml-frameworks-2019-pytorch-dominates-research-tensorflow-dominates-industry. Там говорится, что по большому счету остались только два самых популярных фреймворка: TensorFlow и PyTorch, оба это Python.
    На счёт библиотек на каждый чих, большинство из них давно заброшены, имеют проблемы стабильности и совместимости с новыми версиями языка.
    Вот это все-таки не так. Все хоть как-либо значимые библиотеки уже давно собраны в очень качественные дистрибутивы с полной поддержкой последних версий Python и регулярным обновлением под три платформы: Windows, Linux, Mac. Вот наиболее популярный пакет www.anaconda.com/distribution/#download-section. Мне сложно придумать типовую математическую задачу, которая не была бы уже в том или ином виде реализована в этом дистрибутиве.
  • Julia. С чего начать проект?…
    +2
    Я уже несколько лет активно присматриваюсь к Julia. В основном я пытаюсь заменить Питон для научных расчетов на что-то другое. Но сейчас для меня будущее Julia все-таки под вопросом.

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

    Питон меня полностью устраивает как язык общего уровня. Крайне нравится идеология векторизованных вычислений через NumPy. Но еще пару лет тому назад меня расстраивали три вещи: а) не всегда можно все выразить через NumPy, да и сам NumPy местами медленный, b) GIL, и сложность с параллельными вычислениями и c) отсутствие типизации, что важно для сложных проектов. Все эти проблемы решались через Cython, но код при этом становился крайне плохо читаемым.

    Но за последние несколько лет Python практически решил все эти проблемы: a) появилась Numba, JIT компиляция на лету; теперь достаточно всего пары аннотаций для максимально производительного параллельного кода, b) в python 3.8 появилась концепция субинтерпретаторов с экспериментальным API для shared memory, т.е. проблемы GIL уже почти нет и c) очень неплохая система аннотации типов.

    В настощий момент я на чистом Python (Numpy + Numba) могу написать красивый код (с ясной аннотацией типов), который по производительности не будет уступать Julia. При этом у меня есть широчайшее коммьютнити и библиотеки на каждый чих.

    Но вообще, я очень болею за Julia! Это важный проект для всей области научных расчетов. Мне очень не хватает в Julia простой компиляции в нативный код. Было бы это просто (например, как в nim с его проектом nimpy), я пробовал бы потихоньку на julia писать бинарные модули и использовать из Python.
  • Какой код нужно показывать на собеседовании
    0
    Для простоты пусть все числа будут разными.
  • Какой код нужно показывать на собеседовании
    0
    О! Спасибо за ссылку. Просто он был недоступен у меня пару часов назад. Может что-то у меня не так было.