I'm trying to optimize (for speed) the following code snippet, which

prepares over a million small polygons for rendering. Before you start

asking (what?!), yes there are over a million individual data points

that 1.) have unique properties 2.) can change on the fly. Thus the

DrawPolygon function below is called repeatedly with new datasets.

Yes, using the Polygon API is fairly slow and I'm exploring OpenGL to

remove that lantency. Still, the actual determining of the vertex

placements on the screen is the purpose of the following function.

I'm running a new, pretty high end PC, and am seeing this function

take around .45 seconds to complete in the IDE and around .13 seconds

compiled (with optimizations selected).

This still seems quite slow for a 2.4 GHz Core 2 Duo, considering the

basic math involved. I was hoping that someone might see something

obvious that may help bring this down. The outer loop with the trig

functions actually runs quite fast (taking less than 1ms to complete

for all iterations), so there has to be something with the inner loop

that's causing the problem. My guess is that (at least partially) it's

the Long assigment to the POINTAPI array (as required for the Polygon

API) from the Single variables.

Thanks in advance!

wxforecaster

'REQUIREMENTS: Create a form with a listbox (list1)

'and a timer (timer1) whose interval is set to 10 to spawn this

function frequently.

'Timer APIs

Private Declare Function timeGetTime Lib "winmm.dll" () As Long

Private Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal

uPeriod As Long) As Long

Private Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod

As Long) As Long

Private Type POINTAPI

x As Long

y As Long

End Type

Dim bUnload As Boolean

Const Pi180 As Single = 0.0174533

Public Sub DrawPolygons()

Dim Start As Long

Dim i As Long, j As Long

Dim radarPoly(0 To 3) As POINTAPI

Dim jj As Single, cosaz As Single, sinaz As Single

Dim cosazplus As Single, sinazplus As Single

'Throw in some random approximate values that would be passed to this

function.

'Because these change, we cannot simply store the resultant polygons

in a

'permanant array. Hence the need to optimize the speed here as this

function will be called repeatedly.

Dim HalfWidth As Single: HalfWidth = 300.25

Dim HalfHeight As Single: HalfHeight = 301.13

Dim zoomscl As Single: zoomscl = 2#

Dim zoomwidth As Single: zoomwidth = 0.806667 * zoomscl

Dim zoomheight As Single: zoomheight = 0.8061111 * zoomscl

Dim vlft As Single: vlft = 89.90001 * zoomscl

Dim vtop As Single: vtop = 82.26666 * zoomscl

Dim sf As Single: sf = 0.25

Dim azang As Single, delang As Single

Dim oldx1 As Long, oldx2 As Long, oldy1 As Long, oldy2 As Long

'Create Lookup Table with bin distances

Dim bin_dist() As Single

ReDim bin_dist(1800)

For j = 0 To UBound(bin_dist)

bin_dist(j) = 8 + j * sf

Next j

'Total Loop iterations = 720 (i) * 1800 (j) = 1296000

DoEvents

Start = timeGetTime

'Run outer loop over 720 degrees and calculate some angular based

variables

For i = 1 To 720

azang = i / 2

delang = azang + 0.49

cosaz = Cos((450# - azang) * Pi180)

sinaz = Sin((450# - azang) * Pi180)

cosazplus = Cos((450# - (delang)) * Pi180)

sinazplus = Sin((450# - (delang)) * Pi180)

'Calculate Initial X,Y vertices before entering inner loop

oldx1 = ((HalfWidth + (bin_dist(0) * cosaz)) * zoomwidth)

- vlft

oldy1 = ((HalfHeight - (bin_dist(0) * sinaz)) *

zoomheight) - vtop

oldx2 = ((HalfWidth + (bin_dist(0) * cosazplus)) *

zoomwidth) - vlft

oldy2 = ((HalfHeight - (bin_dist(0) * sinazplus)) *

zoomheight) - vtop

'Run inner loop and calculate vertices for remaining

points

'Since all of our polygons are adjacent within the inner

loop, we only

'need to calculate two new points each iteration and then

save them to

'an variable to avoid the excess math calculations

For j = 1 To 1800

'get zoom/scale adjusted j from lookup table above

jj = bin_dist(j)

'Back left vertex

radarPoly(0).x = oldx1

radarPoly(0).y = oldy1

'Back right vertex

radarPoly(3).x = oldx2

radarPoly(3).y = oldy2

'Front left vertex then assign to Back left

radarPoly(1).x = ((HalfWidth + (jj * cosaz)) *

zoomwidth) - vlft

oldx1 = radarPoly(1).x

radarPoly(1).y = ((HalfHeight - (jj * sinaz)) *

zoomheight) - vtop

oldy1 = radarPoly(1).y

'Front right vertex then assign to Back right

radarPoly(2).x = ((HalfWidth + (jj * cosazplus)) *

zoomwidth) - vlft

oldx2 = radarPoly(2).x

radarPoly(2).y = ((HalfHeight - (jj * sinazplus)) *

zoomheight) - vtop

oldy2 = radarPoly(2).y

'We would then draw our polygon here, passing the

radarPoly() array to

'Polygon API (or eventually OpenGL QUAD_STRIPS)

Next j

Next i

'Place a list box on the form to monitor how long it takes this

function to complete

Call List1.AddItem((timeGetTime - Start) / 1000, 0)

If List1.ListCount >= 100 Then List1.RemoveItem 99

'Calculate running average of the speed to account for fluctuations

Dim sum As Single

For i = 0 To List1.ListCount - 1

sum = sum + CSng(List1.List(i))

Next i

Me.Caption = sum / List1.ListCount

End Sub

Private Sub Form_Load()

'use API to set timer accuracy to 1 ms.

timeBeginPeriod 1

Me.Show

Me.Refresh

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

bUnload = True

End Sub

Private Sub Form_Unload(Cancel As Integer)

'use API to end timer accuracy of 1 ms.

timeEndPeriod 1

Timer1.Interval = 2000

Timer1.Enabled = False

Set Form1 = Nothing

End Sub

Private Sub Timer1_Timer()

If bUnload = True Then Timer1.Enabled = False

DrawPolygons

End Sub