@ elyase велик и справедливо принят. Вот еще одно предположение о том, что если вы можете использовать его, вы можете сделать вызов np.outer
еще быстрее.
Вы говорите: «Я должен делать эту операцию несколько раз», поэтому возможно, что вы можете повторно использовать массив, который содержит внешний продукт, вместо того, чтобы каждый раз назначать новый. Это может дать хорошее повышение производительности.
Во-первых, некоторые случайные данные для работы с:
In [32]: a = np.random.randn(128)
In [33]: b = np.random.randn(32000)
Вот базовое время для np.outer (a, b) на моем компьютер:
In [34]: %timeit np.outer(a, b)
100 loops, best of 3: 5.52 ms per loop
Предположим, что мы будем повторять эту операцию несколько раз с массивами одинаковой формы. Создайте массив out
, чтобы сохранить результат:
In [35]: out = np.empty((128, 32000))
Теперь используйте out
в качестве третьего аргумента np.outer
:
In [36]: %timeit np.outer(a, b, out)
100 loops, best of 3: 2.38 ms per loop
Итак, вы получаете приятное повышение производительности, если вы можете повторно использовать массив, который содержит внешний продукт.
Вы получаете аналогичную выгоду, если вы используете аргумент out
в einsum
и в функции cython, если вы добавляете третий аргумент для вывода вместо выделения его в функции с помощью np.empty
. (Другие компилированные / закодированные коды в ответе @ elyase, вероятно, также выиграют от этого, но я попробовал только версию cython.)
Nota bene! Вышеприведенное преимущество может не реализуются на практике. Массив out
подходит для кэша L3 моего процессора, и когда он используется в цикле, выполняемом командой timeit
, он, вероятно, остается в кеше. На практике массив может быть перемещен из кеша между вызовами np.outer
. В этом случае улучшение не так драматично, но по-прежнему должно быть по меньшей мере стоимость вызова np.empty()
, то есть
In [53]: %timeit np.empty((128, 32000))
1000 loops, best of 3: 1.29 ms per loop
Если вы обнаружите ошибку в коде копирования и вставки, вам нужно будет исправить ее везде, где вы это делали, и надеяться, что вы сможете их все запомнить (это также относится к измененным требованиям) .
Если вы храните логику в одном месте, ее легче изменить при необходимости (поэтому, если вы решите, что приложение нуждается в обновлении, вы делаете это только в одном месте).
Пусть ваш босс прочитает о принципе СУХОЙ (Не повторяйся).
То, что вы описываете, похоже на идеальное использование библиотек , где вы делитесь кодом и храните его только в одном месте.
Я бы копировал-вставлял код только в том случае, если бы намеревался реорганизовать его вскоре после этого - убедившись, что позже я извлечу общий код, чтобы я мог повторно использовать как можно больше логики. И под вскоре после этого я подразумеваю минуты и часы спустя, а не дни и недели.
Я работал в аналогичной компании. Когда я был стажером, тогда я не знал лучшего, поэтому, когда я начал новый проект, мой начальник также предложил вставить код откуда-нибудь еще. Что ж, как вы можете подумать, все программное обеспечение было довольно беспорядочным, вплоть до того, что, когда вы пытались исправить ошибку, появлялись две новые ошибки.
копирование и вставка - это катастрофа, ожидающая своего часа. Ваш начальник должен заранее оценить стоимость доставки по сравнению с ценой очень быстрой доставки неработающего кода конечному пользователю.
Копирование и вставка кода обычно приводит к Программирование по совпадению
Принцип DRY (не повторяйтесь): DRY в википедии .
«Каждая часть знания должна иметь единственное, недвусмысленное, авторитетное представление в системе».
Очевидная причина заключается в том, что вы берете на себя «долг» за будущее: любые изменения, которые вам когда-либо понадобятся в коде (не только исправления ошибок, любые change) теперь будет в два раза дороже, потому что вам нужно обновить два места, и более рискованно, потому что вы в конечном итоге забудете одно из них. Другими словами, если заставить его работать быстрее сейчас, это сделает вашу работу еще медленнее в будущем, что может быть хорошим бизнес-смыслом, но обычно не так.
Но более важная причина в том, что предположение «это то же самое, что и это» чаще всего тонко ошибочно. Всякий раз, когда ваш код зависит от невысказанных предположений, его копирование в другое место приводит к ошибкам, если эти предположения также не выполняются в новом месте. Поэтому вставленный код часто бывает неправильным с самого начала, а не сразу после следующего изменения.
Даже если в другом приложении уже есть необходимая вам функция, код этой функции может просто не вписаться в ваше текущее приложение без серьезного переписывания. Это все равно, что взять двигатель Ford и попытаться втиснуть его в Toyota. Как правило, существует практическое правило: если вам нужно изменить более 25% кода, который вы копируете, лучше (дешевле) переписать его с нуля.
Извлечение рассматриваемого кода в библиотеку звучит убедительно, но это может быть сложнее, чем кажется, в зависимости от того, как построена другая система. Например. код для этой функции может быть трудно извлечь, потому что он взаимодействует с большим количеством другого кода нечистыми способами (например, путем доступа к большому количеству глобальных переменных и т. д.)
Если вы уже реализовали функции и вам нужно копировать и вставлять, чтобы использовать их повторно, похоже, вы сделали что-то не так. Не можете ли вы поместить эти функции в библиотеку, чтобы их можно было использовать повторно без копирования/вставки?
.С точки зрения дизайна, копирование кода - это определенно катастрофа, которая может вызвать множество проблем в будущем. Но вы спрашиваете, почему вам требуется много работы прямо сейчас , ответ такой: потому что это никогда не просто копирование и вставка.
Если исходный код был написан для повторного использования, как довольно независимая библиотека, с учетом гибкости и использования клиента - тогда отлично, но это не копирование, это с использованием библиотеки кода. Реальное копирование кода обычно выглядит примерно так:
Таким образом, существующий код, который нельзя использовать напрямую, в лучшем случае может служить хорошим ориентиром для написания аналогичного кода. Его, конечно, нельзя поднять целиком и ожидать, что он будет работать в совершенно другой системе.В общем, можно с уверенностью предположить, что в любой написанный и завершенный код следует как можно меньше вмешиваться - даже если это копия, а не сам оригинал.
Если вы хотите основать свой проект на копировании-вставке, вам нужно ввести код , чтобы начать с , таким образом, чтобы можно было легко использовать его повторно, без копирования исходного кода. и возиться с этим. Это стоит сделать, и если это то, чего ожидает ваш босс, то вам обоим нужно в первую очередь убедиться, что именно так вы проектируете и работаете.
Вам было бы гораздо лучше совместно использовать код, создавая библиотеку, а не копировать код с помощью копирования и вставки.
Вы по-прежнему получите преимущество в скорости по сравнению с re-написание (поиск DRY), но будет иметь только одно место для ведения кода.
Вы уверены, что ваш босс хочет слышать о принципе DRY, ошибках и других технических вещах?
Подобные комментарии вы обычно слышите, когда ваш босс или Компания недооценила время, необходимое для завершения какого-то проекта. И на основании ошибочной оценки был подписан контракт и т. Д. В большинстве случаев программисты не участвовали в оценках.
Почему это происходит? Иногда у спонсора проекта слишком маленький бюджет. Возможно, бизнес-процесс, который вы автоматизируете с помощью программного обеспечения, не стоит усилий вашей команды. В таких случаях менеджеры обычно очень закрыты для плохих новостей. В начале проекта есть принятие желаемого за действительное. Затем менеджеры пытаются обвинить программистов. В вашем случае косвенно через копирование и вставку. В крайних случаях это называется маршем смерти .
Сообщите своему боссу, что часть имени каждой переменной включает имя старого проекта, и теперь вам нужно изменить их все вручную. Если ваш начальник не знает (или хочет знать), почему копирование / вставка - это плохо, он / она также может поверить, что:)