2010-04-01 2 views
7

Я портирование C++ научного приложения к питону, и, как я новичок в Python, некоторые проблемы приходят на ум:Лучше использовать кортеж или Numpy массив для хранения координат

1) я определяю класс, который будет содержать координаты (x, y). Эти значения будут доступны несколько раз, но они будут прочитаны только после создания экземпляра класса. Лучше ли использовать кортеж или массив numpy, как в памяти, так и в режиме времени?

2) В некоторых случаях эти координаты будут использоваться для построения сложного числа, оцененного по сложной функции, и будет использоваться действительная часть этой функции. Предполагая, что нет возможности разделить реальные и сложные части этой функции, и реальная часть должна быть использована в конце, может быть, лучше использовать непосредственно сложные числа для хранения (x, y)? Насколько плохи накладные расходы с преобразованием от сложного к реальному в python? Код в C++ делает много этих преобразований, и это большое замедление в этом коде.

3) Также необходимо будет выполнить некоторые преобразования координат, а для координат значения x и y будут доступны в отдельности, трансформация будет выполнена, и результат будет возвращен. Преобразования координат определены в комплексной плоскости, поэтому еще быстрее использовать компоненты x и y непосредственно, чем полагаться на комплексные переменные?

Спасибо

+0

Почему бы просто не использовать массив numpy комплексных чисел? – Gabe

+0

Это лучший подход в смысле алгоритма, но, насколько мне показали мои тесты, это самая медленная комбинация. – Ivan

ответ

5

С точки зрения потребления памяти массивы numpy более компактны, чем кортежи Python. Массив numpy использует единый непрерывный блок памяти. Все элементы массива numpy должны иметь объявленный тип (например, 32-битный или 64-битный float.) Кортеж Python необязательно использует непрерывный блок памяти, а элементы кортежа могут быть произвольными объектами Python, которые обычно потребляют больше памяти, чем числовые числовые типы.

Таким образом, эта проблема является выигрышной победой для numpy (при условии, что элементы массива могут быть сохранены в виде числового числового типа).

Что касается скорости, я думаю, что выбор сводится к вопросу: «Можете ли вы оцифровать свой код?»

То есть вы можете выразить свои вычисления как операции, выполняемые по всем массивам по элементам.

Если код может быть векторизован, то numpy скорее всего будет быстрее, чем кортежи Python. (Единственный случай, который я мог себе представить, где это может быть не так, - это если у вас много очень маленьких кортежей. В этом случае накладные расходы на формирование массивов numpy и единовременную стоимость импорта numpy могут заглушить преимущество векторизации.)

пример кода, который не может быть векторизованы бы, если ваш расчет вовлечен глядя на, скажем, первого комплексного числа в массиве z, делая расчет, который производит целочисленный индекс idx, то с извлечением z[idx], делая расчет на это число, которое производит следующий индекс idx2, затем извлекает z[idx2] и т. д. Этот тип расчета может не быть векторизованным.В этом случае вы можете также использовать кортежи Python, так как вы не сможете использовать силу numpy.

Я бы не стал беспокоиться о скорости доступа к реальным/мнимым частям комплексного числа. Я предполагаю, что вопрос о векторизации, скорее всего, определит, какой метод выполняется быстрее. (Хотя, кстати, numpy может преобразовать массив комплексных чисел в их реальные части, просто перейдя по сложному массиву, пропуская все остальные поплавки и просмотрев результат как плавающие. Более того, синтаксис мертв просто: если z . сложный массив NumPy, то z.real это действительные части, как массив с плавающей точкой Numpy Это должно быть гораздо быстрее, чем Python подход чистого использования списка понимания атрибутов поиска в:. [z.real for z in zlist])

Просто из любопытства, что ваша причина для переноса кода на C++ на Python?

+0

Просто проверьте, лучше ли структура объектов Python для моего приложения, и попробуйте выполнить scipy-процедуры. До сих пор я придерживаюсь C++ - на моих тестах, по крайней мере, на 2 порядка быстрее! – Ivan

+0

Кроме того, доступ к реальным и мнимым частям чисел является большим замедлением в коде C++. – Ivan

+0

Да, есть основополагающие причины для использования Python, таких как читаемость и быстрая разработка кода, но я не встречал примеров, когда код был перенесен с C/C++ на Python и получил ускорение. Обычно, когда есть узкое место в коде Python, люди рекомендуют переписать эту функцию в C/C++ и вызывать ее из Python. – unutbu

3

numpy массив с дополнительным измерением плотн в использовании памяти, и, по крайней мере так быстро !, как numpy массив кортежей; сложные числа, по крайней мере, такие же хорошие или даже лучшие, в том числе для вашего третьего вопроса. Кстати, вы, возможно, заметили, что - в то время как вопросы, заданные позже, чем у вас, получались ответы на многие вопросы - вы клали пар: часть причины, несомненно, вызывает вопрос три вопроса вопросов в вопросе. Почему бы просто не задать один вопрос на вопрос? Это не так, как если бы вас обвиняли в вопросах или что-то еще, вы знаете ...! -)

Смежные вопросы