Операция, применяемая map
, является произвольным кодом Python.CPython является интерпретатором, а не JIT-компилятором.
CPython может может иметь некоторые стандартные функции C (заранее скомпилированные как часть интерпретатора) для операций SIMD над массивами, ноэто не AFAIK.Несмотря на это, ему пришлось бы оптимизировать поставляемый func
, чтобы он мог выполнять распознавание образов, чтобы заметить, что, например, он a[i] = max(a[i], some_value)
.
Но обычно CPython не сделать это;издержки интерпретатора - огромная проблема для циклического перебора элементов массива. CPython нигде не близок к производительности собственного скалярного цикла, поэтому есть огромные возможности для выигрыша даже без автоматической векторизации. Как и в 200 раз медленнее IIRC.например, Почему побитовые операторы медленнее, чем умножение / деление / по модулю? показывает, что некоторые операции даже не имеют "быстрого пути" для маленьких целых чисел, и что служебных данных достаточно, чтобы сделать &
медленнее, чем//
, который внутренне использует инструкцию аппаратного деления.
Кроме того, Списки Python не хранятся в виде простых непрерывных массивов int32_t
или double
, поэтому CPU SIMD не работает в любом случае .Вот почему массивы numpy являются особыми: они хранят значения, такие как массив C примитивных типов.
(Предостережение: я почти не знаю Python и не использую его регулярно. Но я думаю, что знаю достаточно дляэтот ответ будет правильным: это интерпретатор, написанный на языке Си, который не выполняет генерацию собственного машинного кода на лету. Единственные собственные циклы, которые могут выполняться, - это те, которые предварительно скомпилированы как часть интерпретатора, или в NumPyбиблиотеки.)