С точки зрения потребления памяти, массивы numpy более компактны, чем кортежи Python.
В массиве numpy используется один непрерывный блок памяти. Все элементы массива numpy должны быть объявленного типа (например, 32-разрядный или 64-разрядный с плавающей запятой.) Кортеж Python не обязательно использует непрерывный блок памяти, а элементы кортежа могут быть произвольными объектами Python, которые обычно потребляет больше памяти, чем числовые типы.
Таким образом, эта проблема является победой для numpy (при условии, что элементы массива могут быть сохранены как числовой тип numpy).
Что касается скорости, я думаю, что выбор сводится к вопросу: «Можете ли вы векторизовать свой код?»
То есть вы можете выразить свои вычисления как операции, выполненные над целыми массивами поэлементно.
Если код может быть векторизован, то numpy, скорее всего, будет быстрее, чем кортежи Python. (Единственный случай, который я мог бы себе представить, где это может быть не так, это если бы у вас было много очень маленьких кортежей. В этом случае накладные расходы на формирование массивов numpy и единовременные затраты на импорт numpy могли бы заглушить выгоду векторизации.)
Примером кода, который нельзя было бы векторизовать, было бы, если бы ваш расчет включал просмотр, скажем, первого комплексного числа в массиве z
, выполнение вычисления, которое дает целочисленный индекс idx
, а затем извлечение z[idx]
, выполняя вычисление для этого числа, которое производит следующий индекс idx2
, затем извлекает z[idx2]
и т. д. Этот тип вычисления может быть не векторизованным. В этом случае вы также можете использовать кортежи Python, поскольку вы не сможете использовать силу numpy.
Я бы не беспокоился о скорости доступа к действительным / воображаемым частям комплексного числа. Я предполагаю, что проблема векторизации, скорее всего, определит, какой метод быстрее. (Хотя, между прочим, numpy может преобразовать массив комплексных чисел в их действительные части, просто перешагнув через сложный массив, пропуская все остальные числа и просматривая результат как числа с плавающей точкой. Более того, синтаксис очень прост: если z
- это сложный массив NumPy, тогда z.real
- это реальные части в виде массива с плавающей точкой. Это должно быть намного быстрее, чем чистый подход Python, использующий понимание списка для поиска атрибутов: [z.real for z in zlist]
.)
Просто из любопытства, какова ваша причина переноса кода C ++ на Python?