473,416 Members | 1,848 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

how can I make this code run faster

I am using the following to compute distances between two lat/long
coordinates for a store locator - (VB .NET 2003)

it seems to take a long time to iterate through like 100-150 locations -
about 10-15 seconds...I want to make the code faster. I changed it to be
multi-threaded, and it doesn't really make it any faster. The bottleneck
seems to be with the math computations.

Any ideas like changing my data types or other ideas etc would be helpful.

Thanks,

--
Scott Emick
Web Programmer
Fox International
Remove the ham from mail address if it's not spam

Option Strict On
Imports System.Threading
Imports Infragistics.Shared
Imports Infragistics.Win
Imports Infragistics.Win.UltraWinGrid

Public Class Locator
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
[...]
#End Region

Public Q As New Queue
Public R As New Queue
Shared rwl As New ReaderWriterLock
Dim dvZip As DataView
Dim srcLat As Double
Dim srcLon As Double
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFind.Click
dvZip = New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim deg As Double
Dim min As Double
Dim sec As Double
dvZip.RowFilter = "ZCODE='" & Microsoft.VisualBasic.Left(txtZip.Text,
5) & "'"

srcLat = CDbl(dvZip(0)("lat"))

srcLon = CDbl(dvZip(0)("lon"))
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow /
DsMM1.Mailing_Master.Count) * 100)
Application.DoEvents()
Q.Enqueue(mmrow)
R.Enqueue(currow)
Dim job3 As New ThreadStart(AddressOf ComputeDistance)
Dim thread3 As New Thread(job3)

thread3.Name = "ComputeDistance"
Do Until R.Count < 20
Loop
thread3.Start()
Next
Dim dvMM01 As New DataView(DsMM1.Mailing_Master)
UltraGrid1.DataSource = dvMM01
dvMM01.Sort = "distance"
dvMM01.RowFilter = "distance<=" & txtMiles.Text
Dim band As UltraGridBand = Me.UltraGrid1.DisplayLayout.Bands(0)
band.Columns("distance").SortIndicator = SortIndicator.Ascending
band.SortedColumns.Add("distance", False, False)
End Sub
Private Sub ComputeDistance()
Dim mmr As dsMM.Mailing_MasterRow = CType(Q.Dequeue,
dsMM.Mailing_MasterRow)
Dim lat As Double
Dim lon As Double
Dim dist As Integer
Dim dvZip2 As New DataView(DsMM1.Zip)
dvZip2.RowFilter = "ZCODE='" & Mid(mmr.MMZIP, 1, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip2(0)("lat"))
lon = CDbl(dvZip2(0)("lon"))
dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
Console.WriteLine(dist)
rwl.AcquireWriterLock(60000)
mmr.Distance = dist
rwl.ReleaseWriterLock()
Else
dist = 2147483647
End If
R.Dequeue()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Show()
txtResults.Text &= "Filling location database..." & vbCrLf
Application.DoEvents()
DsMM1.EnforceConstraints = False
daMM.Fill(DsMM1)
DsMM1.WriteXml("c:\dsmm1.xml")

daZip.Fill(DsMM1)
txtResults.Text &= "Enabling Constraints." & vbCrLf
Try
DsMM1.EnforceConstraints = True
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK)
End
End Try
txtResults.Text &= DsMM1.Mailing_Master.Count.ToString & " locations
available. " & vbCrLf
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim dvZip As New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim lat As Double
Dim lon As Double
Dim deg As Double
Dim min As Double
Dim sec As Double
Dim dist As Integer
Dim srcLat As Double
Dim srcLon As Double
'dvZip.RowFilter = "ZCODE='" & Microsoft.VisualBasic.Left(txtZip.Text,
5) & "'"
'zlat = CStr(dvZip(0)("zlat"))
'deg = CDec(zlat.Substring(0, 2))
'min = CDec(zlat.Substring(2, 2))
'sec = CDec(zlat.Substring(4, 2))
'srcLat = deg + (min / 60) + (sec / 3600)
'zlon = CStr(dvZip(0)("zlon"))
'deg = CDec(zlon.Substring(0, 2))
'min = CDec(zlon.Substring(2, 2))
'sec = CDec(zlon.Substring(4, 2))
'srcLon = deg + (min / 60) + (sec / 3600)
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow / DsMM1.Zip.Count) * 100)
Application.DoEvents()
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(mmrow.MMZIP, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip(0)("LAT"))
mmrow.LAT = CDec(lat)
lon = CDbl(dvZip(0)("LON"))
mmrow.LON = CDec(lon)
daMM.Update(DsMM1.Mailing_Master)
'dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
mmrow.Distance = dist
Else
dist = 2147483647
End If
Next

End Sub
End Class
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String) As
Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
dist = CDbl(rad2deg(dist))
distance = CInt(dist * 60 * 1.1515)
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
If Abs(CDec(rad)) <> 1 Then
acos = pi / 2 - Atan(rad / Sqrt(1 - rad * rad))
ElseIf rad = -1 Then
acos = pi
End If
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts decimal degrees to radians :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function deg2rad(ByVal deg As Double) As Double
deg2rad = CDbl(deg * pi / 180)
End Function

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts radians to decimal degrees :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function rad2deg(ByVal rad As Double) As Double
rad2deg = CDbl(rad * 180 / pi)
End Function

End Class

Nov 23 '05 #1
8 3228
Where are the computations taking place. If you are going back to location
server for the result, it will take a relatively long time ( unless you have
one locally ). If you are making the calculations yourself then without
seeing the code its a little difficult to answer really.

--
Best Regards

The Inimitable Mr Newbie º¿º
"Scott Emick" <se****@ham.fox-international.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I am using the following to compute distances between two lat/long
coordinates for a store locator - (VB .NET 2003)

it seems to take a long time to iterate through like 100-150 locations -
about 10-15 seconds...I want to make the code faster. I changed it to be
multi-threaded, and it doesn't really make it any faster. The bottleneck
seems to be with the math computations.

Any ideas like changing my data types or other ideas etc would be helpful.

Thanks,

--
Scott Emick
Web Programmer
Fox International
Remove the ham from mail address if it's not spam

Option Strict On
Imports System.Threading
Imports Infragistics.Shared
Imports Infragistics.Win
Imports Infragistics.Win.UltraWinGrid

Public Class Locator
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
[...]
#End Region

Public Q As New Queue
Public R As New Queue
Shared rwl As New ReaderWriterLock
Dim dvZip As DataView
Dim srcLat As Double
Dim srcLon As Double
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFind.Click
dvZip = New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim deg As Double
Dim min As Double
Dim sec As Double
dvZip.RowFilter = "ZCODE='" & Microsoft.VisualBasic.Left(txtZip.Text,
5) & "'"

srcLat = CDbl(dvZip(0)("lat"))

srcLon = CDbl(dvZip(0)("lon"))
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow /
DsMM1.Mailing_Master.Count) * 100)
Application.DoEvents()
Q.Enqueue(mmrow)
R.Enqueue(currow)
Dim job3 As New ThreadStart(AddressOf ComputeDistance)
Dim thread3 As New Thread(job3)

thread3.Name = "ComputeDistance"
Do Until R.Count < 20
Loop
thread3.Start()
Next
Dim dvMM01 As New DataView(DsMM1.Mailing_Master)
UltraGrid1.DataSource = dvMM01
dvMM01.Sort = "distance"
dvMM01.RowFilter = "distance<=" & txtMiles.Text
Dim band As UltraGridBand = Me.UltraGrid1.DisplayLayout.Bands(0)
band.Columns("distance").SortIndicator = SortIndicator.Ascending
band.SortedColumns.Add("distance", False, False)
End Sub
Private Sub ComputeDistance()
Dim mmr As dsMM.Mailing_MasterRow = CType(Q.Dequeue,
dsMM.Mailing_MasterRow)
Dim lat As Double
Dim lon As Double
Dim dist As Integer
Dim dvZip2 As New DataView(DsMM1.Zip)
dvZip2.RowFilter = "ZCODE='" & Mid(mmr.MMZIP, 1, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip2(0)("lat"))
lon = CDbl(dvZip2(0)("lon"))
dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
Console.WriteLine(dist)
rwl.AcquireWriterLock(60000)
mmr.Distance = dist
rwl.ReleaseWriterLock()
Else
dist = 2147483647
End If
R.Dequeue()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Show()
txtResults.Text &= "Filling location database..." & vbCrLf
Application.DoEvents()
DsMM1.EnforceConstraints = False
daMM.Fill(DsMM1)
DsMM1.WriteXml("c:\dsmm1.xml")

daZip.Fill(DsMM1)
txtResults.Text &= "Enabling Constraints." & vbCrLf
Try
DsMM1.EnforceConstraints = True
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK)
End
End Try
txtResults.Text &= DsMM1.Mailing_Master.Count.ToString & " locations
available. " & vbCrLf
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim dvZip As New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim lat As Double
Dim lon As Double
Dim deg As Double
Dim min As Double
Dim sec As Double
Dim dist As Integer
Dim srcLat As Double
Dim srcLon As Double
'dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"
'zlat = CStr(dvZip(0)("zlat"))
'deg = CDec(zlat.Substring(0, 2))
'min = CDec(zlat.Substring(2, 2))
'sec = CDec(zlat.Substring(4, 2))
'srcLat = deg + (min / 60) + (sec / 3600)
'zlon = CStr(dvZip(0)("zlon"))
'deg = CDec(zlon.Substring(0, 2))
'min = CDec(zlon.Substring(2, 2))
'sec = CDec(zlon.Substring(4, 2))
'srcLon = deg + (min / 60) + (sec / 3600)
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow / DsMM1.Zip.Count) * 100)
Application.DoEvents()
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(mmrow.MMZIP, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip(0)("LAT"))
mmrow.LAT = CDec(lat)
lon = CDbl(dvZip(0)("LON"))
mmrow.LON = CDec(lon)
daMM.Update(DsMM1.Mailing_Master)
'dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon,
"N")
mmrow.Distance = dist
Else
dist = 2147483647
End If
Next

End Sub
End Class
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String)
As Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
dist = CDbl(rad2deg(dist))
distance = CInt(dist * 60 * 1.1515)
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
If Abs(CDec(rad)) <> 1 Then
acos = pi / 2 - Atan(rad / Sqrt(1 - rad * rad))
ElseIf rad = -1 Then
acos = pi
End If
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts decimal degrees to radians :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function deg2rad(ByVal deg As Double) As Double
deg2rad = CDbl(deg * pi / 180)
End Function

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts radians to decimal degrees :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function rad2deg(ByVal rad As Double) As Double
rad2deg = CDbl(rad * 180 / pi)
End Function

End Class

Nov 23 '05 #2
Well unless you are running the proggy on a MP systems multithreading will
make your proggy only slower

some tips to improve speed :

use the smallest possible datatype
use as less loops as possible and break out when possible
use the compiler optimization ( this can speed up calcs by 20% ) however
use it only if you know that a overflow will not occur in your situation
use as less "Try catch statements as possible " it is better to check a
result and return a value as to rely on a error to occur and then return a
value ( this costs much more as the latter ) try catch statements are verry
costly so use them only if you have no other option

do not use doevents !! if you need to repaint a progressbar , label etc
use the refresh / update method of the control

regards

Michel Posseth [MCP]

"Scott Emick" <se****@ham.fox-international.com> schreef in bericht
news:%2****************@tk2msftngp13.phx.gbl...
I am using the following to compute distances between two lat/long
coordinates for a store locator - (VB .NET 2003)

it seems to take a long time to iterate through like 100-150 locations -
about 10-15 seconds...I want to make the code faster. I changed it to be
multi-threaded, and it doesn't really make it any faster. The bottleneck
seems to be with the math computations.

Any ideas like changing my data types or other ideas etc would be helpful.

Thanks,

--
Scott Emick
Web Programmer
Fox International
Remove the ham from mail address if it's not spam

Option Strict On
Imports System.Threading
Imports Infragistics.Shared
Imports Infragistics.Win
Imports Infragistics.Win.UltraWinGrid

Public Class Locator
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
[...]
#End Region

Public Q As New Queue
Public R As New Queue
Shared rwl As New ReaderWriterLock
Dim dvZip As DataView
Dim srcLat As Double
Dim srcLon As Double
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFind.Click
dvZip = New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim deg As Double
Dim min As Double
Dim sec As Double
dvZip.RowFilter = "ZCODE='" & Microsoft.VisualBasic.Left(txtZip.Text,
5) & "'"

srcLat = CDbl(dvZip(0)("lat"))

srcLon = CDbl(dvZip(0)("lon"))
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow /
DsMM1.Mailing_Master.Count) * 100)
Application.DoEvents()
Q.Enqueue(mmrow)
R.Enqueue(currow)
Dim job3 As New ThreadStart(AddressOf ComputeDistance)
Dim thread3 As New Thread(job3)

thread3.Name = "ComputeDistance"
Do Until R.Count < 20
Loop
thread3.Start()
Next
Dim dvMM01 As New DataView(DsMM1.Mailing_Master)
UltraGrid1.DataSource = dvMM01
dvMM01.Sort = "distance"
dvMM01.RowFilter = "distance<=" & txtMiles.Text
Dim band As UltraGridBand = Me.UltraGrid1.DisplayLayout.Bands(0)
band.Columns("distance").SortIndicator = SortIndicator.Ascending
band.SortedColumns.Add("distance", False, False)
End Sub
Private Sub ComputeDistance()
Dim mmr As dsMM.Mailing_MasterRow = CType(Q.Dequeue,
dsMM.Mailing_MasterRow)
Dim lat As Double
Dim lon As Double
Dim dist As Integer
Dim dvZip2 As New DataView(DsMM1.Zip)
dvZip2.RowFilter = "ZCODE='" & Mid(mmr.MMZIP, 1, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip2(0)("lat"))
lon = CDbl(dvZip2(0)("lon"))
dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
Console.WriteLine(dist)
rwl.AcquireWriterLock(60000)
mmr.Distance = dist
rwl.ReleaseWriterLock()
Else
dist = 2147483647
End If
R.Dequeue()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Show()
txtResults.Text &= "Filling location database..." & vbCrLf
Application.DoEvents()
DsMM1.EnforceConstraints = False
daMM.Fill(DsMM1)
DsMM1.WriteXml("c:\dsmm1.xml")

daZip.Fill(DsMM1)
txtResults.Text &= "Enabling Constraints." & vbCrLf
Try
DsMM1.EnforceConstraints = True
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK)
End
End Try
txtResults.Text &= DsMM1.Mailing_Master.Count.ToString & " locations
available. " & vbCrLf
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim dvZip As New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim lat As Double
Dim lon As Double
Dim deg As Double
Dim min As Double
Dim sec As Double
Dim dist As Integer
Dim srcLat As Double
Dim srcLon As Double
'dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"
'zlat = CStr(dvZip(0)("zlat"))
'deg = CDec(zlat.Substring(0, 2))
'min = CDec(zlat.Substring(2, 2))
'sec = CDec(zlat.Substring(4, 2))
'srcLat = deg + (min / 60) + (sec / 3600)
'zlon = CStr(dvZip(0)("zlon"))
'deg = CDec(zlon.Substring(0, 2))
'min = CDec(zlon.Substring(2, 2))
'sec = CDec(zlon.Substring(4, 2))
'srcLon = deg + (min / 60) + (sec / 3600)
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow / DsMM1.Zip.Count) * 100)
Application.DoEvents()
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(mmrow.MMZIP, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip(0)("LAT"))
mmrow.LAT = CDec(lat)
lon = CDbl(dvZip(0)("LON"))
mmrow.LON = CDec(lon)
daMM.Update(DsMM1.Mailing_Master)
'dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon,
"N")
mmrow.Distance = dist
Else
dist = 2147483647
End If
Next

End Sub
End Class
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String)
As Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
dist = CDbl(rad2deg(dist))
distance = CInt(dist * 60 * 1.1515)
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
If Abs(CDec(rad)) <> 1 Then
acos = pi / 2 - Atan(rad / Sqrt(1 - rad * rad))
ElseIf rad = -1 Then
acos = pi
End If
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts decimal degrees to radians :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function deg2rad(ByVal deg As Double) As Double
deg2rad = CDbl(deg * pi / 180)
End Function

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts radians to decimal degrees :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function rad2deg(ByVal rad As Double) As Double
rad2deg = CDbl(rad * 180 / pi)
End Function

End Class

Nov 23 '05 #3
I may be missing something, but it seems to me that calculating the distance
between two long/lat coordinates should take milliseconds. 150 calculations
should be done in under a second.

How long is the database query itself taking to return the rows?

Try running a stripped down version of the code, removing everything except
the select and the calculation. Take out all the multithreading, progress
bar, do events, etc. Limit it to:
Select some data from table
for each record in table
console.writeline(calcdistance)
next

See how long the code takes to run like this. I suspect it will be very
fast. Once the barbones calc is running reasonably fast, you can start
adding other pieces back in to see what is slowing you down.
"Scott Emick" <se****@ham.fox-international.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I am using the following to compute distances between two lat/long
coordinates for a store locator - (VB .NET 2003)

it seems to take a long time to iterate through like 100-150 locations -
about 10-15 seconds...I want to make the code faster. I changed it to be
multi-threaded, and it doesn't really make it any faster. The bottleneck
seems to be with the math computations.

Any ideas like changing my data types or other ideas etc would be helpful.

Thanks,

--
Scott Emick
Web Programmer
Fox International
Remove the ham from mail address if it's not spam

Option Strict On
Imports System.Threading
Imports Infragistics.Shared
Imports Infragistics.Win
Imports Infragistics.Win.UltraWinGrid

Public Class Locator
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
[...]
#End Region

Public Q As New Queue
Public R As New Queue
Shared rwl As New ReaderWriterLock
Dim dvZip As DataView
Dim srcLat As Double
Dim srcLon As Double
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFind.Click
dvZip = New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim deg As Double
Dim min As Double
Dim sec As Double
dvZip.RowFilter = "ZCODE='" & Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"

srcLat = CDbl(dvZip(0)("lat"))

srcLon = CDbl(dvZip(0)("lon"))
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow /
DsMM1.Mailing_Master.Count) * 100)
Application.DoEvents()
Q.Enqueue(mmrow)
R.Enqueue(currow)
Dim job3 As New ThreadStart(AddressOf ComputeDistance)
Dim thread3 As New Thread(job3)

thread3.Name = "ComputeDistance"
Do Until R.Count < 20
Loop
thread3.Start()
Next
Dim dvMM01 As New DataView(DsMM1.Mailing_Master)
UltraGrid1.DataSource = dvMM01
dvMM01.Sort = "distance"
dvMM01.RowFilter = "distance<=" & txtMiles.Text
Dim band As UltraGridBand = Me.UltraGrid1.DisplayLayout.Bands(0)
band.Columns("distance").SortIndicator = SortIndicator.Ascending
band.SortedColumns.Add("distance", False, False)
End Sub
Private Sub ComputeDistance()
Dim mmr As dsMM.Mailing_MasterRow = CType(Q.Dequeue,
dsMM.Mailing_MasterRow)
Dim lat As Double
Dim lon As Double
Dim dist As Integer
Dim dvZip2 As New DataView(DsMM1.Zip)
dvZip2.RowFilter = "ZCODE='" & Mid(mmr.MMZIP, 1, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip2(0)("lat"))
lon = CDbl(dvZip2(0)("lon"))
dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
Console.WriteLine(dist)
rwl.AcquireWriterLock(60000)
mmr.Distance = dist
rwl.ReleaseWriterLock()
Else
dist = 2147483647
End If
R.Dequeue()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Show()
txtResults.Text &= "Filling location database..." & vbCrLf
Application.DoEvents()
DsMM1.EnforceConstraints = False
daMM.Fill(DsMM1)
DsMM1.WriteXml("c:\dsmm1.xml")

daZip.Fill(DsMM1)
txtResults.Text &= "Enabling Constraints." & vbCrLf
Try
DsMM1.EnforceConstraints = True
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK)
End
End Try
txtResults.Text &= DsMM1.Mailing_Master.Count.ToString & " locations
available. " & vbCrLf
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim dvZip As New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim lat As Double
Dim lon As Double
Dim deg As Double
Dim min As Double
Dim sec As Double
Dim dist As Integer
Dim srcLat As Double
Dim srcLon As Double
'dvZip.RowFilter = "ZCODE='" & Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"
'zlat = CStr(dvZip(0)("zlat"))
'deg = CDec(zlat.Substring(0, 2))
'min = CDec(zlat.Substring(2, 2))
'sec = CDec(zlat.Substring(4, 2))
'srcLat = deg + (min / 60) + (sec / 3600)
'zlon = CStr(dvZip(0)("zlon"))
'deg = CDec(zlon.Substring(0, 2))
'min = CDec(zlon.Substring(2, 2))
'sec = CDec(zlon.Substring(4, 2))
'srcLon = deg + (min / 60) + (sec / 3600)
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow / DsMM1.Zip.Count) * 100)
Application.DoEvents()
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(mmrow.MMZIP, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip(0)("LAT"))
mmrow.LAT = CDec(lat)
lon = CDbl(dvZip(0)("LON"))
mmrow.LON = CDec(lon)
daMM.Update(DsMM1.Mailing_Master)
'dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N") mmrow.Distance = dist
Else
dist = 2147483647
End If
Next

End Sub
End Class
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String) As Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
dist = CDbl(rad2deg(dist))
distance = CInt(dist * 60 * 1.1515)
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
If Abs(CDec(rad)) <> 1 Then
acos = pi / 2 - Atan(rad / Sqrt(1 - rad * rad))
ElseIf rad = -1 Then
acos = pi
End If
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts decimal degrees to radians :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function deg2rad(ByVal deg As Double) As Double
deg2rad = CDbl(deg * pi / 180)
End Function

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts radians to decimal degrees :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function rad2deg(ByVal rad As Double) As Double
rad2deg = CDbl(rad * 180 / pi)
End Function

End Class

Nov 23 '05 #4
"Scott Emick" wrote
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
What's wrong with Math.Pi ?
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String)
As Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
But they're already doubles - take out all the CDbl() to make it more
readable. And maybe convert the angles to radians before even starting that
calculation.
distance = CInt(dist * 60 * 1.1515)
So, why's the following code in there - you've just exited the function.
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
Umm, if that code gets a chance to execute, what happens if UCase(unit) is
neither "K" nor "N"?

const deg2rad as double=pi/180
const rad2deg as double=180/pi
' convert to radians
lat1=lat1*deg2rad
lat2=lat2*deg2rad
' find angle between coordinates
dist= acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(( lon2-lon1))*deg2rad)
select case UCase(unit)
case("K")
' return as kilometres???
distance=int(dist*60*1.1515*1.609344*rad2deg)
case("N")
' return as nautical miles???
distance=int(dist*60*1.1515*0.8684*rad2deg)
case else
' default to (statute?) miles???
distance=int(dist*60*1.1515*rad2deg)
end select

You forgot to put in comments as to what your constants 1.1515 etc.
represent. Maybe a comment that surface distance=radius*subtended angle
would be useful, seeing as you're using a variable named dist to represent
an angle.

I suspect your theta should be lon2-lon1, but since cos(x)=cos(-x) you're
not going to see any difference.

It may look neater to have deg2rad as a function, but if you're desperate
for faster code then write it in yourself (a quick look at the help didn't
suggest any way to in-line a function in VB.NET).
...
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
...


Don't you like Math.Acos() ?

Andrew
Nov 23 '05 #5
Thanks - I do know to use the smallest datatype possible, but I need to
figure out just what that is for lat/long computations.

I am using doevents, so I will nix that in favor of the update/refresh for
my progress bar. The computations are occuring locally. I will also try
the compiler optimization as there should never be a divide by zero or bad
data problem.

Thanks very much all

Scott Emick
"m.posseth" <po*****@planet.nl> wrote in message
news:Ob**************@TK2MSFTNGP12.phx.gbl...
Well unless you are running the proggy on a MP systems multithreading will
make your proggy only slower

some tips to improve speed :

use the smallest possible datatype
use as less loops as possible and break out when possible
use the compiler optimization ( this can speed up calcs by 20% ) however
use it only if you know that a overflow will not occur in your situation
use as less "Try catch statements as possible " it is better to check a
result and return a value as to rely on a error to occur and then return a
value ( this costs much more as the latter ) try catch statements are
verry costly so use them only if you have no other option

do not use doevents !! if you need to repaint a progressbar , label etc
use the refresh / update method of the control

regards

Michel Posseth [MCP]

"Scott Emick" <se****@ham.fox-international.com> schreef in bericht
news:%2****************@tk2msftngp13.phx.gbl...
I am using the following to compute distances between two lat/long
coordinates for a store locator - (VB .NET 2003)

it seems to take a long time to iterate through like 100-150 locations -
about 10-15 seconds...I want to make the code faster. I changed it to be
multi-threaded, and it doesn't really make it any faster. The bottleneck
seems to be with the math computations.

Any ideas like changing my data types or other ideas etc would be
helpful.

Thanks,

--
Scott Emick
Web Programmer
Fox International
Remove the ham from mail address if it's not spam

Option Strict On
Imports System.Threading
Imports Infragistics.Shared
Imports Infragistics.Win
Imports Infragistics.Win.UltraWinGrid

Public Class Locator
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
[...]
#End Region

Public Q As New Queue
Public R As New Queue
Shared rwl As New ReaderWriterLock
Dim dvZip As DataView
Dim srcLat As Double
Dim srcLon As Double
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFind.Click
dvZip = New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim deg As Double
Dim min As Double
Dim sec As Double
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"

srcLat = CDbl(dvZip(0)("lat"))

srcLon = CDbl(dvZip(0)("lon"))
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow /
DsMM1.Mailing_Master.Count) * 100)
Application.DoEvents()
Q.Enqueue(mmrow)
R.Enqueue(currow)
Dim job3 As New ThreadStart(AddressOf ComputeDistance)
Dim thread3 As New Thread(job3)

thread3.Name = "ComputeDistance"
Do Until R.Count < 20
Loop
thread3.Start()
Next
Dim dvMM01 As New DataView(DsMM1.Mailing_Master)
UltraGrid1.DataSource = dvMM01
dvMM01.Sort = "distance"
dvMM01.RowFilter = "distance<=" & txtMiles.Text
Dim band As UltraGridBand = Me.UltraGrid1.DisplayLayout.Bands(0)
band.Columns("distance").SortIndicator = SortIndicator.Ascending
band.SortedColumns.Add("distance", False, False)
End Sub
Private Sub ComputeDistance()
Dim mmr As dsMM.Mailing_MasterRow = CType(Q.Dequeue,
dsMM.Mailing_MasterRow)
Dim lat As Double
Dim lon As Double
Dim dist As Integer
Dim dvZip2 As New DataView(DsMM1.Zip)
dvZip2.RowFilter = "ZCODE='" & Mid(mmr.MMZIP, 1, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip2(0)("lat"))
lon = CDbl(dvZip2(0)("lon"))
dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
Console.WriteLine(dist)
rwl.AcquireWriterLock(60000)
mmr.Distance = dist
rwl.ReleaseWriterLock()
Else
dist = 2147483647
End If
R.Dequeue()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Show()
txtResults.Text &= "Filling location database..." & vbCrLf
Application.DoEvents()
DsMM1.EnforceConstraints = False
daMM.Fill(DsMM1)
DsMM1.WriteXml("c:\dsmm1.xml")

daZip.Fill(DsMM1)
txtResults.Text &= "Enabling Constraints." & vbCrLf
Try
DsMM1.EnforceConstraints = True
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK)
End
End Try
txtResults.Text &= DsMM1.Mailing_Master.Count.ToString & " locations
available. " & vbCrLf
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim dvZip As New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim lat As Double
Dim lon As Double
Dim deg As Double
Dim min As Double
Dim sec As Double
Dim dist As Integer
Dim srcLat As Double
Dim srcLon As Double
'dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"
'zlat = CStr(dvZip(0)("zlat"))
'deg = CDec(zlat.Substring(0, 2))
'min = CDec(zlat.Substring(2, 2))
'sec = CDec(zlat.Substring(4, 2))
'srcLat = deg + (min / 60) + (sec / 3600)
'zlon = CStr(dvZip(0)("zlon"))
'deg = CDec(zlon.Substring(0, 2))
'min = CDec(zlon.Substring(2, 2))
'sec = CDec(zlon.Substring(4, 2))
'srcLon = deg + (min / 60) + (sec / 3600)
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow / DsMM1.Zip.Count) * 100)
Application.DoEvents()
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(mmrow.MMZIP, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip(0)("LAT"))
mmrow.LAT = CDec(lat)
lon = CDbl(dvZip(0)("LON"))
mmrow.LON = CDec(lon)
daMM.Update(DsMM1.Mailing_Master)
'dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon,
"N")
mmrow.Distance = dist
Else
dist = 2147483647
End If
Next

End Sub
End Class
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String)
As Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
dist = CDbl(rad2deg(dist))
distance = CInt(dist * 60 * 1.1515)
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
If Abs(CDec(rad)) <> 1 Then
acos = pi / 2 - Atan(rad / Sqrt(1 - rad * rad))
ElseIf rad = -1 Then
acos = pi
End If
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts decimal degrees to radians :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function deg2rad(ByVal deg As Double) As Double
deg2rad = CDbl(deg * pi / 180)
End Function

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts radians to decimal degrees :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function rad2deg(ByVal rad As Double) As Double
rad2deg = CDbl(rad * 180 / pi)
End Function

End Class


Nov 23 '05 #6
I tried the optimization and remove integer overflow checks and that did
improve the speed somewhat. What was interesting to me was that removing
this following:

Const pi As Double = 3.1415926535897931

and simply using the .net framework's built in Pi make code execution about
30% faster.

All in all it is running much faster and smoother mostly due to:

1. Removing the application.doevents
2. Using the built-in Pi function

Thanks again,

Scott Emick
Software Engineer
Fox International
"m.posseth" <po*****@planet.nl> wrote in message
news:Ob**************@TK2MSFTNGP12.phx.gbl...
Well unless you are running the proggy on a MP systems multithreading will
make your proggy only slower

some tips to improve speed :

use the smallest possible datatype
use as less loops as possible and break out when possible
use the compiler optimization ( this can speed up calcs by 20% ) however
use it only if you know that a overflow will not occur in your situation
use as less "Try catch statements as possible " it is better to check a
result and return a value as to rely on a error to occur and then return a
value ( this costs much more as the latter ) try catch statements are
verry costly so use them only if you have no other option

do not use doevents !! if you need to repaint a progressbar , label etc
use the refresh / update method of the control

regards

Michel Posseth [MCP]

"Scott Emick" <se****@ham.fox-international.com> schreef in bericht
news:%2****************@tk2msftngp13.phx.gbl...
I am using the following to compute distances between two lat/long
coordinates for a store locator - (VB .NET 2003)

it seems to take a long time to iterate through like 100-150 locations -
about 10-15 seconds...I want to make the code faster. I changed it to be
multi-threaded, and it doesn't really make it any faster. The bottleneck
seems to be with the math computations.

Any ideas like changing my data types or other ideas etc would be
helpful.

Thanks,

--
Scott Emick
Web Programmer
Fox International
Remove the ham from mail address if it's not spam

Option Strict On
Imports System.Threading
Imports Infragistics.Shared
Imports Infragistics.Win
Imports Infragistics.Win.UltraWinGrid

Public Class Locator
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
[...]
#End Region

Public Q As New Queue
Public R As New Queue
Shared rwl As New ReaderWriterLock
Dim dvZip As DataView
Dim srcLat As Double
Dim srcLon As Double
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFind.Click
dvZip = New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim deg As Double
Dim min As Double
Dim sec As Double
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"

srcLat = CDbl(dvZip(0)("lat"))

srcLon = CDbl(dvZip(0)("lon"))
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow /
DsMM1.Mailing_Master.Count) * 100)
Application.DoEvents()
Q.Enqueue(mmrow)
R.Enqueue(currow)
Dim job3 As New ThreadStart(AddressOf ComputeDistance)
Dim thread3 As New Thread(job3)

thread3.Name = "ComputeDistance"
Do Until R.Count < 20
Loop
thread3.Start()
Next
Dim dvMM01 As New DataView(DsMM1.Mailing_Master)
UltraGrid1.DataSource = dvMM01
dvMM01.Sort = "distance"
dvMM01.RowFilter = "distance<=" & txtMiles.Text
Dim band As UltraGridBand = Me.UltraGrid1.DisplayLayout.Bands(0)
band.Columns("distance").SortIndicator = SortIndicator.Ascending
band.SortedColumns.Add("distance", False, False)
End Sub
Private Sub ComputeDistance()
Dim mmr As dsMM.Mailing_MasterRow = CType(Q.Dequeue,
dsMM.Mailing_MasterRow)
Dim lat As Double
Dim lon As Double
Dim dist As Integer
Dim dvZip2 As New DataView(DsMM1.Zip)
dvZip2.RowFilter = "ZCODE='" & Mid(mmr.MMZIP, 1, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip2(0)("lat"))
lon = CDbl(dvZip2(0)("lon"))
dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon, "N")
Console.WriteLine(dist)
rwl.AcquireWriterLock(60000)
mmr.Distance = dist
rwl.ReleaseWriterLock()
Else
dist = 2147483647
End If
R.Dequeue()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Show()
txtResults.Text &= "Filling location database..." & vbCrLf
Application.DoEvents()
DsMM1.EnforceConstraints = False
daMM.Fill(DsMM1)
DsMM1.WriteXml("c:\dsmm1.xml")

daZip.Fill(DsMM1)
txtResults.Text &= "Enabling Constraints." & vbCrLf
Try
DsMM1.EnforceConstraints = True
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK)
End
End Try
txtResults.Text &= DsMM1.Mailing_Master.Count.ToString & " locations
available. " & vbCrLf
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim dvZip As New DataView(DsMM1.Zip)
Dim mmrow As dsMM.Mailing_MasterRow
Dim zlat As String
Dim zlon As String
Dim lat As Double
Dim lon As Double
Dim deg As Double
Dim min As Double
Dim sec As Double
Dim dist As Integer
Dim srcLat As Double
Dim srcLon As Double
'dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(txtZip.Text, 5) & "'"
'zlat = CStr(dvZip(0)("zlat"))
'deg = CDec(zlat.Substring(0, 2))
'min = CDec(zlat.Substring(2, 2))
'sec = CDec(zlat.Substring(4, 2))
'srcLat = deg + (min / 60) + (sec / 3600)
'zlon = CStr(dvZip(0)("zlon"))
'deg = CDec(zlon.Substring(0, 2))
'min = CDec(zlon.Substring(2, 2))
'sec = CDec(zlon.Substring(4, 2))
'srcLon = deg + (min / 60) + (sec / 3600)
Dim currow As Integer
For Each mmrow In DsMM1.Mailing_Master
currow += 1
UltraProgressBar1.Value = CInt((currow / DsMM1.Zip.Count) * 100)
Application.DoEvents()
dvZip.RowFilter = "ZCODE='" &
Microsoft.VisualBasic.Left(mmrow.MMZIP, 5) & "'"
If dvZip.Count > 0 Then
lat = CDbl(dvZip(0)("LAT"))
mmrow.LAT = CDec(lat)
lon = CDbl(dvZip(0)("LON"))
mmrow.LON = CDec(lon)
daMM.Update(DsMM1.Mailing_Master)
'dist = LocatorLib.Calcs.distance(srcLat, srcLon, lat, lon,
"N")
mmrow.Distance = dist
Else
dist = 2147483647
End If
Next

End Sub
End Class
'Below is from a class in a library project (dll)
Option Strict On
Imports System.Math
Public Class Calcs
Const pi As Double = 3.1415926535897931
Public Shared Function distance(ByVal lat1 As Double, ByVal lon1 As
Double, ByVal lat2 As Double, ByVal lon2 As Double, ByVal unit As String)
As Integer
Dim theta As Double, dist As Double
theta = lon1 - lon2
dist = Sin(CDbl(deg2rad(lat1))) * Sin(CDbl(deg2rad(lat2))) +
Cos(CDbl(deg2rad(lat1))) * Cos(CDbl(deg2rad(lat2))) *
Cos(CDbl(deg2rad(theta)))
dist = CDbl(acos(dist))
dist = CDbl(rad2deg(dist))
distance = CInt(dist * 60 * 1.1515)
Select Case UCase(unit)
Case "K"
distance = CInt(distance * 1.609344)
Case "N"
distance = CInt(distance * 0.8684)
End Select
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function get the arccos function from arctan function :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function acos(ByVal rad As Double) As Double
If Abs(CDec(rad)) <> 1 Then
acos = pi / 2 - Atan(rad / Sqrt(1 - rad * rad))
ElseIf rad = -1 Then
acos = pi
End If
End Function
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts decimal degrees to radians :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function deg2rad(ByVal deg As Double) As Double
deg2rad = CDbl(deg * pi / 180)
End Function

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
'::: this function converts radians to decimal degrees :::
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::
Public Shared Function rad2deg(ByVal rad As Double) As Double
rad2deg = CDbl(rad * 180 / pi)
End Function

End Class


Nov 23 '05 #7
> ' return as kilometres???
distance=int(dist*60*1.1515*1.609344*rad2deg)


Another rather small optimisation is pre-solving all constant results
yourself beforehand like in this line.

distance=int(dist*60*1.1515*1.609344*rad2deg)

That could easily be replaced by

distance=int(dist*111.18957696*rad2deg)

Ofcourse it's just 2 multiplications you take out, but if it's
optimising you're looking for every bit helps :)
--
Rinze van Huizen
C-Services Holland b.v
Nov 23 '05 #8
C-Services Holland b.v. wrote:
' return as kilometres???
distance=int(dist*60*1.1515*1.609344*rad2deg)


Another rather small optimisation is pre-solving all constant results
yourself beforehand like in this line.

distance=int(dist*60*1.1515*1.609344*rad2deg)

That could easily be replaced by

distance=int(dist*111.18957696*rad2deg)

Ofcourse it's just 2 multiplications you take out, but if it's
optimising you're looking for every bit helps :)


But that's part of the compiler's job, surely? And as rad2deg was defined as
a constant, it should do that product too.

Leaving the values individually editable helps when reading the code, or
editing it if, say, the mile is redefined.

Andrew
Nov 23 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: hasadh | last post by:
Hi, is the assemly code for if..else and switch statements similar. I would like to know if switch also uses value comparison for each case internally or does it jump to the case directly at...
10
by: Henrik Andersen | last post by:
Hi newsgroup Does the c++ compiler generate faster code at execution time than the C# compiler? Does the c++ compiler have more optimisations than the C# compiler? Thanks in advance!
3
by: jesper | last post by:
I would like some feedback on this. A while back I was trying my hand at some pathfinding for a small game I was making. I did not know anything about it so I read some stuff and came up with the...
60
by: Dave | last post by:
I'm never quite sure whether to use "this." or not when referring to fields or properties in the same class. It obviously works just fine without it but sometimes I wonder if using this....
10
by: Extremest | last post by:
I know there are ways to make this a lot faster. Any newsreader does this in seconds. I don't know how they do it and I am very new to c#. If anyone knows a faster way please let me know. All...
7
by: Wisgary | last post by:
I'm doing some benchmarking tests to compare Microsoft's CLR against Mono's CLR. I could use some suggestions for how to objectively compare the code. To my surprise the few tests I've run so far...
12
by: vunet.us | last post by:
Is there a suggestion I can make this code run faster: if(document.getElementById("1")){ doOne(); } if(document.getElementById("2")){ doTwo(); } .......................
23
by: Python Maniac | last post by:
I am new to Python however I would like some feedback from those who know more about Python than I do at this time. def scrambleLine(line): s = '' for c in line: s += chr(ord(c) | 0x80)...
3
by: Alpha83 | last post by:
Hi, Is there a code measuring tool that tells you which is more efficient cost-wise. For example, if I were to compare the following two identical code blocks, how do I know, which is more...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.