Нормально получать выбросы, если (например) ваш процесс переносится на другой процессор во время выполнения. (Таким образом, все обращения к памяти некоторое время пропадают в кеше, потому что в L1d и L2 на предыдущем ядре было жарко). Это может случиться и в реальной жизни.
Таким образом, вы должны решить, что вы хотите измерить: «нормальный» случай, в котором нет ничего странного, или полный дистрибутив, включая наихудший случай.
Это определенно не нормальное гауссовское распределение, если вы сохраняете выбросы, поэтому возьмите любую статистику с частичкой соли, если они основаны на этом предположении!
Если вы хотите исключить выбросы, закрепите частоту процессора и прикрепите процесс к одному ядру. Но вы все равно можете получить выбросы, когда обработчик прерываний или другая задача ядра выполняет значительный объем работы с этим ядром, сбой страницы или что-то еще.
Или на ЦП с Hyperthreading, если другой поток работает на логическом ядре одного и того же физического ядра. Или другая задача на том же компьютере конкурирует за общие ресурсы, такие как пропускная способность памяти или объем кэша, или дисковый ввод-вывод.
Если вы достаточно знаете о том, что делает ваша функция и как ее выполняет Python, вы можете быть достаточно уверены, что выбросы не являются «реальными», то есть что у вашего процесса не было ЦП для большинства этих настенных часов. время или миграция ЦП, тогда вы можете просто отбросить выбросы выше некоторого порога.
Или посмотрите среднее время вместо среднего. Медиана не чувствительна к огромным выбросам, но все равно будет реагировать на изменения.
Если вы синхронизируете с одним и тем же входом несколько раз, так что вы ожидаете, что функция займет одно и то же время, вы можете взять минимум. (Обычно по существу равный медиане.)