2013-05-26 4 views
2

Я использую закон косинусов в программе, и это кажется медленной точкой моего кода. Это строка кода, которая у меня есть:Оптимизация права косинусов в VB.net

Ans = Math.Sqrt(A^2 + B^2 - 2 * A * B * Math.Cos(C - D)) 

Где А-D - это двойные переменные, которые меняются каждый раз при вызове. Кажется, что для этой функции требуется около 2000 тиков. Я рассмотрел использование малой угловой аппроксимации, где if (C-D) достаточно мал, вы можете использовать cos (C-D) = 1 - ((C-D)^2)/2. К сожалению, это оказалось более медленным, чем исходный код. Я рассмотрел любые отношения, которые могут быть использованы для упрощения расчета, но A и C связаны сложным образом, и B и D связаны одинаково, нет никакой связи между A и B или между C и D .

Я думал об использовании функции поиска для всех значений (CD), но моя точность в настоящее время составляет по крайней мере 6 значительных цифр, и я предпочел бы оставаться на этом уровне, поскольку это точность моих входных данных , короче говоря, это означает около миллиона ваулей в поиске, и это всего лишь 1 часть функции. Я думал о поиске всех четырех значений (A, B, C и D), но я не уверен, как это реализовать.

Я также многопользовал это приложение и попытался использовать GPGPU (GPGPU оказался медленнее из-за времени, затрачиваемого на загрузку и выключение памяти GPU).

Итак, мой вопрос заключается в том, как ускорить эту функцию.

Спасибо, продвинутый!

+0

что тип переменной? Вы увидите замедление, если используете decmal. –

ответ

3

Следующие работает в менее чем 1/3 времени

ANS = Math.Sqrt (а * а + Ь * б - 2 * A * B * Math.cos (C - D))

Вот код, который доказывает это:

Dim sw1 As New Stopwatch 
    Dim sw2 As New Stopwatch 

    Dim ans, a, b, c, d As Double 
    a = 5 
    b = 10 
    c = 4 
    d = 2 

    sw1.Start() 
    For x As Integer = 1 To 10000 
     ans = Math.Sqrt(a^2 + b^2 - 2 * a * b * Math.Cos(c - d)) 
    Next 
    sw1.Stop() 

    sw2.Start() 
    For y As Integer = 1 To 10000 
     ans = Math.Sqrt(a * a + b * b - 2 * a * b * Math.Cos(c - d)) 
    Next 
    sw2.Stop() 

    Console.WriteLine(sw1.ElapsedTicks) 
    Console.WriteLine(sw2.ElapsedTicks) 

    Console.WriteLine(sw2.ElapsedTicks * 100/sw1.ElapsedTicks)