Pull to refresh

Comments 64

так сколько строк-то?)

Если вкратце, точно неизвестно, сколько; известно только, что много.

https://news.ycombinator.com/item?id=38600216
whizzter 2 days ago
If you read the article you can see that some codepaths can invoke Malloc with all the follow-on effects like Kernel boundary crossings that this implies, it's thus quite random.

https://news.ycombinator.com/item?id=38634480
whizzter 7 hours
Depends, I look at it from a performance standpoint when starting to count lines/instructions, not just directly executed code but also how feasible it would be to translate the thing to a JIT for example, the amount is large enough that going to a JIT would yield little (this is why there has been so many Python JIT's that has failed to gain enough performance and hence traction) before mayor architectural fixes are made.
Not only is there branches to a ton of special things but also macros that hides even more lines (IncRef/DecRef probably has a lot of magic behind there).

Можно скачать сорцы питона, собрать их с lcov и посмотреть, что будет для разных типов. Потом написать скрипт, который пройдет по репорту и сделает операцию +(желательно разные репорты для разных типов).

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

Чисто на саму операцию плюс для какого нить инта, думаю в пару тысяч строк уложиться вполне реально.

А если скомпилировать через cython ? В этом случае правда код не прогоняется через виртуальную машину.

Если ничего не делать - ничего не изменится. Чтобы код в cython стал занимать 1 строку всем переменным (a, b и результат) должны быть определены типы (например через cdef)

1) Я пропустил или рассказан шаг приведения типов, как например для случая int + float или float + int?

2) В некоторых местах кривой или неверный перевод;

"Структура PyTypeObject хранит подробности о типе среды исполнения об объекте" - это как понять по-русски?

1} В разделе Создание экземпляров типов Float при помощи PyNumberMethods

Вы пропустили, внутри самой функции сложения float_add() вызывается CONVERT_TO_DOUBLE()

То есть, при 1 + 1 числа переводятся в double?

"Структура PyTypeObject хранит подробности о типе среды исполнения об объекте" - это как понять по-русски?

Забавно, гуглопереводчик справился лучше:

Структура PyTypeObject хранит сведения о типе объекта во время выполнения, такие как имя типа, размер типа, функции для выделения и освобождения объекта этого типа.

Забавно, гуглопереводчик справился лучше:

да ничего забавного, вы попробуйте что нибудь попереводить дажа гуглопереводчиком на 5 минут чтения, и не сделать ни одной смысловой ошибки даже просто при копировании.

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

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

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

Старанная тема - чего ее мусолить. Никто же не откажется от языка, на котором уже написано куча кода, даже зная что есть другие более эффективные инструменты.

Полезная информация. Ещё хотелось бы узнать сколько полупроводников задействовано в сим происходящем.

Меня также интересует количество электронов задействованных в этом бардаке? Электрон сейчас дорог знаете ли.

Электрон сейчас дорог знаете ли.

Зато дырки пока что бесплатны. Для снижения издержек надо больше использовать полупроводники p-типа )

Борзый какой, пойдем за орбиталь выйдем

"И эти люди запрещают мне ковыряться в носу"

Сдаётся мне что даже Visual Basic был эффективнее с точки зрения производительности. В тезис про упрощение жизни програмиста я тоже не особо верю т.к. изучить весь зоопарк библиотек Питона практически нереально, а без доступа 24/7 к StackOverflow и Гуглу вообще невозможно.

Почему «даже»?

Вопреки гуляющим в сети бредням, что VB интерпретируемый язык, по умолчанию при генерации исполняемых файлов среда генерировала IL-код в том формате, в каком происходило взаимодействие между фронтендом и бэкендом компилятора Microsoft Visual C/C++ — и этот IL скармливался бэкенду.

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

Если не быть чудаком и использовать типизированные переменные скалярных типов, а не тип Variant — код получался настолько же хорошим, как аналогичный сильный код, с той оговоркой, что в код вставлялись проверки, чтобы не выстрелить себе в ногу. Да и то, эти проверки были весьма легковесными — например, проверка на переполнение после операции сложения делалась одной единственной инструкцией JO/JNO, проверяющей OF. Но и подобный проверки во многом можно было отключить в настройках оптимизации.

Не по умолчанию — это компиляция в P-code. Так назывался байт-код собственной виртуальной машины VB/VBA. Этот вариант всегда использования в режиме отладки, потому что позволяло чрезвычайно бонато и гибко править код по живому в процессе запуска в режиме отладки. В этом случае операции проводились короткими обработчиками соответствующих P-codeных инструкций, которые были написаны на ассемблере и вылизаны, насколько это было возможно.

Операции над типом Variant в любом случае выполнялись при помощи API-функций ил OLEAUT32.DLL.

Спасибо. Я хотел сравнить с интерпретатором, неловко получилось ))

Если продолжать: VB (и в равной степени VBA) это, пожалуй, уникальная среда, где интерпретирование кода (парсинг, разбор) происходило в момент набора кода в редакторе, и с тех пор, как программист нажал Enter (или другим способом перешёл на другую строку), строка кода под капотом вообще больше не существует как текст.

Лишь для целей отрисовки на экране избранные строки реконструировались обратно в цветной текст из исходно не текстового представления.

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

то ли дело luajit

local function f(a, b) return a + b end
local s = 0
for i = 1, 512 do s = f(s, i) end
print(s)

luajit -jdump 1.lua
---- TRACE 1 mcode 100
000e7f9c sub sp, sp, #8
000e7fa0 str r9, [sp, #8]
000e7fa4 movw r0, #23000
000e7fa8 movt r0, #46810
000e7fac ldr r10, [r9, #16]
000e7fb0 ldrd r4, [r9]
000e7fb4 cmn r5, #9
000e7fb8 blne 0x000e0018 ->0
000e7fbc ldrd r6, [r9, #8]
000e7fc0 cmn r7, #14
000e7fc4 blne 0x000e0018 ->0
000e7fc8 cmp r4, r0
000e7fcc blne 0x000e0018 ->0
000e7fd0 adds r11, r6, r10
000e7fd4 blvs 0x000e0018 ->0
000e7fd8 add r10, r10, #1
000e7fdc cmp r10, #512
000e7fe0 blgt 0x000e001c ->1
->LOOP:
000e7fe4 mov r9, r11
000e7fe8 adds r11, r10, r9
000e7fec blvs 0x000e0020 ->2
000e7ff0 add r10, r10, #1
000e7ff4 cmp r10, #512
000e7ff8 ble 0x000e7fe4 ->LOOP
000e7ffc bl 0x000e0024 ->3
---- TRACE 1 stop -> loop

Аж несколько кодов на ассемблере. Ну, это, конечно, лукавая цифра

BLVS не пометили. Это обработка переполнения после сложения.

Собственно, а зачам наизусть учить весь зоопарк библиотек любого языка? Программировать без доступа к документации - это прям очень специфичные условия работы. А то что регулярно и каждодневно используется и так останется на кончиках пальцев.

Сколько телодвижений, когда разработчик настолько обленился, что не способен определиться, переменные какого типа он хочет сложить.

С учетом того, сколько процессорного времени=энергии тратится на такую элементарную операцию, питон никакая не зелёная технология. А черная

Теперь понятно почему им так в Германии заинтересовались.

Так нет смысла оптимизировать сложение двух целочисленных значений. А для сложения миллиарда значений на си придется или специализированные библиотеки применять (и писать избыточный код), или писать кучу кода для использования симд, векторизации и многотопочного выполнения, а на питоне достаточно декларацию numba добавить и/или объявить массивы как объекты numpy. Практика показывает, что код на питоне почти всегда быстрее сишного (потому что все названные оптимизации на си практически никто не делает). При желании, код на питоне и ассемблерный обгоняет, периодически разработчики публикуют примеры.

Да что уж там мелочиться. Код на питоне и CPU на котором работает обгоняет. Просто бежит впереди декодера и подкладывает библиотеки

Идиотские шутки оставьте для более подходящего места, а по теме - numba на лету из кода питона создает очень неплохой ассемблерный код с учетом векторизации и прочего, см. https://numba.pydata.org Написанный человеком ассемблерный код зачастую медленнее, тесты в сети есть.

Питон быстрее c/c++ потому что numba для генерации ассемблера использует LLVM! Не то что C/C++, RUST которые тоже умеют в LLVM... Ой.

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

Вот только программисты на С/С++ ассемблерный код почти никогда не смотрят, потому что уверены, что и так быстрее некуда. А там бывают очень странные фокусы, зависящие от компилятора. Как правило, даже без numba просто на numpy программа на питоне заметно быстрее типовой на си на сложной обработке больших данных.

Это правда. Но где то же должен быть водороздел, между крутышами и не очень.

Язык глвбокт вторичен в данном случае. Abyway типовой python медленее типового c/c++ по причине разных задач и приоритетов.

А кому надо и htttp://godbolt.org могут открыть и зарплату свое распальцевать.

Типовый питон подразумевает использование numpy, scipy и прочих вычислительных библиотек, плюс dask, joblib и прочих для параллельного и кластерного выполнения и так далее. Также в одну строчку numba подключается и компилирует код. Так что программист одного уровня на питоне пишет код куда компактнее и оптимальнее, нежели на си. Чтобы научиться грамотно использовать в питоне joblib, надо потратить пару дней, а вот на OpenMP в си нужно пару лет. Более того, компилятор от эппл OpenMP не поддерживает вовсе, OpenMP библиотека в Conda собрана gcc 8 и с более новым не собирается в принципе, а в Homebrew собрана без поддержки фортрана и надо ее пересобирать, но с новыми gcc не собирается (а старые не поддерживают актуальный фортран), и так далее. С openMPI все еще хуже, потому что реализаций много, в том числе проприетарных, и на каждом университетском unix кластере оказывается своя со своими «особенностями» (разнящимися от версии к версии и на разных платформах). На моей практике, хуже научного софта на Си только софт на матлабе - и по качеству кода и по быстродействию, а на питоне и код прочитать можно и работает быстрее.

Типовый питон это не только научный питон, питон аналитический или ml. Часто это in-house тестирование, разработка вебсайтов и прототипипования. Часто в случае с последним, если взлетает, берут и переписывают на более быстрый язык.

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

Проблемы с библиотеками чаще всего решаются тем, что у тебя функционал переходит в стандарт, либо in-house решения аналогичные по функционалу.

Все эти быстрые и замечательные библиотеки питона, в основной под капотом c/c++, а в некоторых случаях даже fortran. Так что конфликт языков в данном случае, больше конфликт инфраструктуры языка. И да распарсить json нифига не юзер френдли для c++ или c, но и далеко не такая большая проблема. Зато можно получить результаты которые нужны именно тебе, и это будет быстрее и куда контроллируемее, что в случае с c/c++ очень ценно. Да и с точки бизнеса тоже.

У вас очень оторванные от жизни абстрактные рассуждения. Еще пять лет назад я писал библиотеки для питона на Си и иногда фортране (потому что многомерные массивы поддерживаются, причем не надо руками векторизацию делать), последние годы переписал все на питоне с выигрышем по производительности и куда меньшим объемом кода. Вот пример софта спутниковой интерферометрии на питоне для обработки терабайтов радарных космоснимков: https://github.com/mobigroup/gmtsar Проект написан в свободное время, притом работает в разы быстрее сишных аналогов и довольствуется 8-16 ГБ оперативки там, где софт на си требует терабайты. Похожий проект с меньшим функционалом команда разработчиков на си писала лет двадцать, притом что вычисления однопоточные, память выделяется сразу подо все и так далее. А вы рассказываете, как на си все прекрасно - нет, отнюдь, потому что трудоемкость написания равного по производительности кода раз в 100 выше, то есть это недостижимо для небольшого коллектива, а сотню сишных разработчиков со знанием соответствующих алгоритмов вы вообще никогда не соберете (у Дональда Кнута вы не найдете распределенного вычисления интерферограмм и прочего, все надо самому разрабатывать). В питоновских библиотеках есть свои проблемы, как и в интерпретаторе и их активно чинят, в то время как в Си, кажется, никогда не будет даже поддержки фортрановских многомерных массивов. Признаться, порой прототипы вычислений пишу на си (потому что знаю его 20+ лет и привык), потом переписываю на питон и проверяю, чтобы работало быстрее, и это всегда возможно.

Я чет не понял что мешает теже библиотеки подключить в C? Какой то странный и не понятный мне аргумент, "питон быстрый потому что у него есть быстрые библиотеки", так они и для C/C++ есть

Ваш сарказм необоснован. Большая часть программ в основном висит заблокированная на IO: ожидает пакет из сети, чтения из файла, ввода от юзера. Что Си что Пайтон имеют ждать одинаково эффективно :) И ждать будут одинаковое количество времени.

Да, есть класс вычислительных задач где скорость вычисления a + b имеет значение. Но для таких задач никто не будет писать a + b ни в си, ни на пайтоне. А будут использовать специализированные библиотеки, которые умеют складывать числа сильно быстрее, чем наивный код на си или пайтоне. О чем собственно@N-Cubeи написал. Непонятно за что его минусуют.

Вствлю пять копеек.
Нам надо было написать некую хитрую обработку изображений.
Первая версия была на Питоне - почему? Потому что был рядом человек который умел работать с изображениями только на Питоне. И да, один файл обрабатывался пять часов. Мы убедились в работоспособности идеи и переписали на Си. Файл стал обрабатыватсья три минуты.

Такая разница в производительности может говорить лишь о том, что человек не умеет писать на питоне производительный код, т.е. не использует библиотеки типа opencv, numpy, scipy, numba.

Я могу поверить разнице времени в несколько раз между реализацией на Питоне и Си, но разница ровно в 100 раз могла возникнуть только из-за плохого кода на Питоне.

Так проблема в том, что 99% программистов на Питоне не умеют писать производительный код. Они не для этого его учили, а для того, чтобы было "как проще".

Программисты на си ровно так же не умеют. Скажем, могут написать многомерный фильтр Гаусса в виде многомерной итерации по по всей окрестности каждого элемента - практически в любом научном софте найдете (см. GMT, GMTSAR и еще неисчислимое множество известного софта). Зато в питоне авторы библиотеки scipy знают, что это можно сделать в тысячи и миллионы раз быстрее с помощью набора одномерных фильтров. Идем дальше - тот же фильтр Гаусса для больших сигма сишные программисты никогда на моей памяти даже не пытаются оптимизировать как последовательность фильтров, ну и так далее. В итоге, фильтрацию терабайтного растра на ноутбуке на питоне можно выполнить за минуту, а на си - за неделю. В теории, можно и на си грамотно написать, но я за четверть века не встречал ни одной адекватной реализации простейшего фильтра Гаусса на си, не говоря уж о чем-то посложнее.

Тут не проблема производительности платформы. А просто нежелание или отсутствие необходимости делать оптимизацию.

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

Ни когда я не пойду писать условный фильтр гауса руками в прод, если я не разрабатываю библиотеку для подобных задачь, нафига мне это делать?

Первым делом я пойду гуглить готовую либу желательно с перфтестами.

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

Вы загрузили изображение в трёхмерный массив (третье - по цветам) из нативных lists и нативных числовых типов? Не надо так. Даже в стандартной библиотеке Питона есть модуль array для таких случаев.

Увы - я не умею на Питоне.Я поставил задачу - есть видеофайл, надо расставить на движущемся изображении точки, потом взять интенсивность в этих точках и посчитать по вот таким формулам. Как именно это делалось - не знаю.

Тогда поясню. В отличие от других языков, в Питоне "примитивные типы" - числа и массивы - нифига не примитивные. Они набиты проверками на ошибки, что очень полезно когда они есть в единичном экземпляре. Но когда начинаются хоть какие-то вопросы к производительности или потреблению памяти, то их использовать нельзя, а нужно из отдельной библиотеки типа Numpy вытащить настоящие примитивы - те, которые как и в Си, весят 4-8 байтов на штуку, при переполнении тихо врут а не дают эксепшн, и прочие радости.

Те, кто этому не научился, раскладывают данные в стандартные массивы, и смотрят как 200кб у них в памяти занимает 20Мб. А виноват Питон, конечно.

Ну вот, началось в колхозе утро... А я то надеялся, что Питон это что-то типа современного Бейсика и его все учат потому что просто. Даже реклама постоянно попадается: "Почему лучше учить сложный C++, чем простые Python/Java" ))).

"Простой" для входа не значит простой по устройству. Скорее даже наоборот: чем проще взаимодействие с человеком, тем сложнее внутренняя структура. А у питона оказался еще удачный баланс между легкостью входа и глубиной доступа к оптимизациям.

Так всегда - знаете ассемблер, будете лучше писать на си, знаете си, будете лучше писать на питоне. Не знаете ничего - лучше начать с питона, чем с ассемблера, иначе вообще можете ничего не написать. Понадобится - можно для питона писать библиотеки на си с ассемблерными вставками, а можно просто использовать numba и писать на питоне как на си.

Тут вопрос насколько честно говорить о быстродействии "кода на питоне", если этот код лишь дергает библиотеку в которой задача была эффективно решена при помощи другого языка программирования.

А на си для быстродействия вставки на ассемблере и библиотеки на фортране используют. В питоне можно numba применять, будет еще быстрее numpy выполняться, притом многопоточность и распределенное выполнение реализуются куда проще и эффективнее, чем на си.

А в попугаях на ассемблере будет ещё больше!

А это цена за элементарность, а также за динамическое типизирование.

Элементарный в использовании не означает элементарный в реализации.

В подписе к первой картинке:

Реализация выбирается в зависимости от того, какой тип имеют a и b: int, float или сложный тип

А на картинке написано “complex”. Это действительно есть такой тип, как «сложный», или это всё-таки комплексное число?

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

Сколько строк на C нужно, чтобы выполнить a + b в Python?

Много, учитывая объём кода самого интерпретатора Python))

Исполнение кодов что на c что на питоне будет одинаковым. Потому что оба языка обращаются к одним и тем же подтипам ассемблера.

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

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

Автор толком не обосновал тот факт, что применение молотка и микроскопа в забивании гвоздя может быть одинаково эффективным. Но все мы должны понимать для чего молоток а для чего микроскоп.

Sign up to leave a comment.

Articles