В основном я делаю программу на Java, которая должна будет довольно быстро выполнять множество вычислений (каждый кадр, стремясь как минимум к 30 кадрам в секунду). В основном это будут тригонометрические и степенные функции. Вопрос, который я задаю: что быстрее: использование математических функций, уже предоставленных Java? Или писать свои собственные функции для запуска?
Пользовательские математические функции и поставляемые математические функции?
Ответы (5)
Встроенные функции Math
будет чрезвычайно трудно превзойти, учитывая, что большинство из них имеют особую магию JVM, которая заставляет их использовать аппаратные встроенные функции. Вы могли бы вероятно превзойти некоторые из них, пожертвовав точностью много работы, но в противном случае вы вряд ли превзойдете Math
утилиты. .
pow()
, что приводит к множеству особых случаев] .
- person njuffa; 16.01.2015
Вы захотите использовать функции java.lang.Math
, так как большинство из них запускают native
в JVM. вы можете увидеть исходный код здесь.
Многие очень умные и высококвалифицированные люди в течение многих лет прикладывали много усилий для того, чтобы математические функции работали как можно быстрее и точнее. Так что, если вы не умнее их всех и у вас есть годы свободного времени, чтобы потратить на это, очень маловероятно, что вы сможете работать лучше.
Большинство из них тоже нативные — на самом деле они не на Java. Так что писать их более быстрые версии на Java не получится. Вам, вероятно, лучше всего использовать смесь C и языка ассемблера, когда вы начинаете писать свой собственный; и вам нужно знать все особенности любого оборудования, на котором вы собираетесь это запускать.
Более того, текущие реализации проверены на протяжении многих лет тем фактом, что миллионы людей по всему миру так или иначе используют Java. У вас не будет доступа к одному и тому же набору тестировщиков, поэтому ваши функции автоматически будут более подвержены ошибкам, чем стандартные. Это неизбежно.
Итак, вы все еще думаете о написании собственных функций?
Если вы можете выдержать относительную ошибку 1e-15ish (или больше похожую на 1e-13ish для pow(double,double)), вы можете попробовать это, что должно быть быстрее, чем java.lang.Math, если вы его часто называете: http://sourceforge.net/projects/jafama/
Как некоторые говорили, обычно трудно превзойти java.lang.Math в чистой Java, если вы хотите сохранить аналогичную (1-ulp-ish) точность, но немного меньшая точность в двойной точности часто вполне терпима (и все же гораздо больше точнее, чем при вычислениях с числами с плавающей запятой), и может обеспечить некоторое заметное ускорение.
Что может быть вариантом, так это кэширование значений. Если вы знаете, что вам понадобится только фиксированный набор значений или если вы можете обойтись без идеальной точности, это может сэкономить много времени. Скажем, если вы хотите нарисовать много кругов, предварительно вычислите значения sin и cos для каждой степени. Затем используйте эти значения при рисовании. Большинство кругов будут достаточно маленькими, чтобы вы не могли увидеть разницу, а небольшое количество очень больших кругов можно сделать с помощью библиотек.
Обязательно протестируйте, стоит ли оно того. На моем 5-летнем макбуке я могу делать миллион оценок cos в секунду.
java.lang.Math
не имеет нужной вам функции, наверняка кто-то еще решил ту же проблему и написал библиотека для ее решения. На самом деле, здесь не изобретено (синдром NIH) — широко известный антишаблон в разработке программного обеспечения, тесно связанный с связанных с изобретением велосипеда. - person gknicker   schedule 16.01.2015