2015-01-15 7 views
0

Я в основном делаю Java-программу, которая должна быстро выполнить множество вычислений (каждый кадр, рассчитанный не менее 30 f/s). В основном это тригонометрические и силовые функции. Вопрос, который я задаю, это: Что происходит быстрее: с помощью уже заданных Java-математических функций? Или написать мои собственные функции для запуска?Пользовательские математические функции и заданные математические функции?

+0

Объективный ответ заключается в том, что это зависит от того, насколько хорошо вы можете это сделать, и так далее. –

+0

Как правило, в большинстве библиотек математических функций для языка всегда есть быстрее, чем те, которые вы предоставляете, поскольку они имеют возможность оптимизации способами, которые вам недоступны (если вы не пишете ваш в ассемблере). –

+0

Даже если 'java.lang.Math' не имеет функции, вам нужно, что кто-то другой решил ту же проблему и написал [библиотеку для ее решения] (http://stackoverflow.com/questions/ 7258538/свободный Java-библиотека-для-оценки-математические-выражения). Фактически, [не изобретенный здесь] (http://en.wikipedia.org/wiki/Not_invented_here) (синдром NIH) - это общеизвестный антипаттерн в разработке программного обеспечения, тесно связанный с [изобретать колесо] (http: // en .wikipedia.org/вики/Reinventing_the_wheel). – gknicker

ответ

8

Функциональность встроенных функций Math будет чрезвычайно сложной, учитывая, что у большинства из них есть специальная магия JVM, которая заставляет их использовать аппаратные возможности. Вы могли бы предположительно избили некоторые из них, торгуя точностью с лот работы, но вы вряд ли побьете Math утилит иначе.

+2

Хотя я согласен с общей оценкой, создание пользовательских функций может не обязательно потребовать много работы в зависимости от навыка программиста и ограничений, накладываемых на функции (-ы). Более низкая точность - всего лишь один возможный компромисс, другие поддерживают только ограниченный диапазон аргументов [особенно полезный в случае тригонометрических функций] и не имея дело со специальными случаями [очень полезными для 'pow()', что приводит к большим партиям особых случаев]. – njuffa

1

Вы должны использовать функции java.lang.Math, поскольку большинство из них запускают native в JVM. вы можете увидеть исходный код here.

+0

Даже методы, которые не являются родными, могут быть неотъемлемыми, то есть код Java никогда не запускается и заменяется на время выполнения JVM более эффективным кодом. – assylias

1

Многие из очень умных и квалифицированных людей приложили много усилий в течение многих лет к тому, чтобы математические функции работали как можно быстрее и точно. Поэтому, если вы не умнее всех, и у вас есть годы свободного времени, чтобы потратить на это, маловероятно, что вы сможете сделать лучшую работу.

Большинство из них тоже родные - на самом деле они не на Java. Поэтому писать более быстрые версии из них в Java будет полным не-go. Вероятно, вам лучше всего использовать смесь языка C и Assembly, когда вы приходите писать сами; и вам нужно знать все причуды любого оборудования, на котором вы собираетесь запускать это.

Кроме того, текущие реализации были протестированы на протяжении многих лет тем фактом, что миллионы людей во всем мире используют Java в некотором роде. У вас не будет доступа к те же тестеры, поэтому ваши функции будут автоматически подвержены ошибкам, чем стандартные. Это неизбежно.

Вы все еще думаете о написании собственных функций?

0

Что может быть опцией - это кеширование значений. Если вы знаете, что вам понадобится только фиксированный набор значений, или если вы сможете уйти без совершенной точности, это может сэкономить много времени. Скажем, если вы хотите нарисовать много кругов, предварительно вычислить значения sin и cos для каждой степени. Затем используйте эти значения при рисовании. Большинство кругов будут достаточно маленькими, чтобы вы не могли видеть разницу, а небольшое число, которое очень велико, можно сделать с помощью библиотек.

Обязательно проверьте, действительно ли это стоит. На моем 5-летнем macbook я могу сделать миллион оценок cos секунду.

1

Если вы можете получить относительную ошибку 1e-15ish (или больше похожую на 1e-13ish для pow (double, double)), вы можете попробовать это, что должно быть быстрее, чем java.lang.Math, если вы это назовете : http://sourceforge.net/projects/jafama/

Как утверждают некоторые, обычно трудно превзойти java.lang.Math в чистой Java, если вы хотите сохранить аналогичную точность (1-ulp-ish), но немного меньше точности в двойной точности часто полностью (и, тем не менее, гораздо точнее, чем то, что у вас было бы при вычислении с помощью float), и может позволить некоторое заметное ускорение.

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