Подтвердить что ты не робот

Точное тестирование производительности Pypy vs CPython

Описание проблемы:

У меня есть эта пользовательская функция "контрольной суммы":

NORMALIZER = 0x10000


def get_checksum(part1, part2, salt="trailing"):
    """Returns a checksum of two strings."""

    combined_string = part1 + part2 + " " + salt if part2 != "***" else part1
    ords = [ord(x) for x in combined_string]

    checksum = ords[0]  # initial value

    # TODO: document the logic behind the checksum calculations
    iterator = zip(ords[1:], ords)
    checksum += sum(x + 2 * y if counter % 2 else x * y
                    for counter, (x, y) in enumerate(iterator))
    checksum %= NORMALIZER

    return checksum

Что я хочу протестировать как на Python3.6, так и на PyPy. Я хотел бы увидеть, будет ли функция работать лучше на PyPy, но я не совсем уверен, что является самым надежным и чистым способом сделать это.

Что я пробовал и вопрос:

В настоящее время я использую timeit для обоих:

$ python3.6 -mtimeit -s "from test import get_checksum" "get_checksum('test1' * 100000, 'test2' * 100000)"
10 loops, best of 3: 329 msec per loop

$ pypy -mtimeit -s "from test import get_checksum" "get_checksum('test1' * 100000, 'test2' * 100000)"
10 loops, best of 3: 104 msec per loop

Мое беспокойство заключается в том, что я не совсем уверен, что timeit - это правильный инструмент для работы на PyPy из-за потенциальных JIT-разминков.

Кроме того, PyPy сам сообщает следующее, прежде чем сообщать результаты теста:

WARNING: timeit is a very unreliable tool. use perf or something else for real measurements
pypy -m pip install perf
pypy -m perf timeit -s 'from test import get_checksum' "get_checksum('test1' * 1000000, 'test2' * 1000000)"

Какой был бы лучший и самый точный подход для тестирования одинаковой производительности функции в этих и потенциально других реализациях Python?

4b9b3361

Ответ 1

Вы можете увеличить количество повторений с помощью параметра --repeat, чтобы улучшить точность синхронизации. см:

https://docs.python.org/2/library/timeit.html

Ответ 2

Не совсем ясно, что вы пытаетесь измерить. "Производительность" может означать различные вещи в зависимости от вашего прецедента.

  • Вы пытаетесь измерить необработанную скорость функции после того, как все разогрето (JIT, в частности, а также импорт библиотеки, загрузка файла и т.д.)? Тогда вы, вероятно, захотите --repeat много чего предложить Haroldo_OK. При достаточном количестве повторений время, проведенное в других частях вашего кода, будет постепенно "незначительным".
  • Вы измеряете вещи ради обучения или для использования в реальном мире? Если последнее, вероятно, неплохо проверить свой код в аналогичных условиях (длина строк, которые вы передаете своей функции, количество итераций, теплый/холодный вызов вашего кода...). Мое впечатление, что использование python interface вместо CLI даст вам больше гибкости, чтобы точно определить, что вы после.

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

Если вы пытаетесь улучшить скорость, используйте профайлер, например cProfile, который поддерживается как Python3.6, так и pypy может помочь с изолированием кода, скорость которого вы хотите измерить?

Я не отвечаю на ваш вопрос, но надеюсь, что это поможет:)