Speedwise, как Pharo сравнивается с Python3?

У меня нет большого опыта в программировании, но я немного знаю Python3, и сейчас я делаю свои первые детские шаги в изучении Pharo. Я все еще не знаком с объектно-ориентированным программированием или обозревателем классов, но я уже прошел учебник ProfStef и играюсь с небольшими программами на Playground, чтобы ознакомиться с синтаксисом.

Одной из первых вещей, которые меня заинтересовали, было сравнение двух языков с точки зрения скорости, поскольку я где-то читал, что в Pharo встроен JIT-компилятор. Поэтому я написал небольшой причудливый скрипт на обоих языках, который генерирует 8 миллионов чисел. , фильтрует 1/3 из них, вычисляет 1/sqrt(x) для каждого, суммирует результаты и повторяет процесс сто раз, каждый раз немного изменяя интервалы, снова суммируя результаты в конце и измеряя время всего процесса. . Не правильный тест, просто упражнение, чтобы получить оценку порядка величины, но я старался, чтобы обе версии были как можно более похожими.

Версия Python 3:

import time, math

mega = lambda n: sum([1/math.sqrt(1 + i + n) for i in range(8000000) if (i + 1) // 3 == 0])
start = time.time()
print(sum([mega(n + 1) for n in range(100)]))
stop = time.time() - start
print(stop)

Результаты с Python 3.8.5 (по умолчанию, 28 июля 2020 г., 12:59:40):

34.7701230607214
52.75216603279114

Фаро 8 версия:

| mega range start stop |.

range := [:n | (((1 to: 8000000) select: [:j | (j quo: 3) = 0]) collect: [:i | 1 / (n + i) sqrt]) sum].
start := DateAndTime  now.
Transcript show: (((1 to: 100) collect: [:n | range value: n]) sum); cr.
stop := (DateAndTime now - start) asSeconds.
Transcript show: stop; cr.

Результаты на Pharo-8.0.0+build.1141.sha.1b7a8d8203fce2a57794451f555bba4222614081 (64 бит):

34.7701230607214
45

Как я и ожидал, версия Pharo работала быстрее, но с небольшим отрывом, 45 секунд против чуть более 52 секунд для Python. Это заняло примерно на 13% меньше времени. Так что я предполагаю, что их скорость примерно одного порядка. Это типичная ситуация?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
844
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Такой тест мало о чем говорит. Основная причина в том, что основная часть вычислений состоит в многократной отправке одних и тех же сообщений экземплярам одних и тех же классов (quo: и = для select: и /, +, sqrt для collect: и т. д.). Это означает, что трудоемкая (внутренняя) операция, такая как поиск метода, выполняется только один раз, а затем задерживается во встроенных кэшах. В результате у вас может быть система, которая превосходит другую при выполнении этих тестов и намного медленнее при запуске «настоящего» приложения. Помимо (моно или полиморфных) встроенных кешей, которые уменьшают потребность в поиске методов, другие методы, которые имеют значение, — это производительность сборщика мусора, встраивание методов (которое заменяет отправляющие сайты копией целевого кода), размещение регистров. (для минимизации доступа к памяти), производительность сообщения become: и т. д. Множество факторов делает желательным измерение более сложных фрагментов кода, пытаясь использовать известные узкие места, как те, которые я только что упомянул. Иногда небольшое изменение может выявить скрытые сильные (или слабые) стороны вашей системы. Поэтому я предлагаю, чтобы для проведения такого рода анализа вы должны немного постараться и разработать тесты, направленные на измерение того, как система реагирует на определенный вид стресса.

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

kleite 12.12.2020 23:47

Хотя это еще не так идиоматически,

| range start stop |.

range := [ :n | (1 to: 8000000) inject: 0 into: [:sum :in | 
    ((in quo: 3) = 0 )
        ifTrue: [1 / ( n + in) sqrt + sum] 
        ifFalse: [sum]]].
start := DateAndTime  now.
Transcript show: (((1 to: 100) collect: [:n | range value: n]) sum); cr.
stop := (DateAndTime now - start) asSeconds.
Transcript show: stop; cr.

в 2,5 раза быстрее. Что как бы подчеркивает точку зрения Леандро.

Я запустил вашу версию на своей машине, и на самом деле это заняло всего 19 секунд. Впечатляющий! Спасибо.

kleite 20.12.2020 16:43

Другие вопросы по теме