提高VB运行速度
下面是我的代码:
Dim temrecord2(360, 1) As Long
Dim i, j, k, l, f As Integer
Dim count As Integer
Dim cx, cy, csx, csy As Long
Dim jl As Single
For l = 0 To 360
For i = 0 To 360
If i - l < 0 Then
temrecord(i, 0) = record(i - l + 360, 0)
Else
temrecord(i, 0) = record(i - l, 0)
End If
temrecord(i, 1) = 1
Next
For f = 0 To 360
For j = 0 To 360
csx = Int((basicrecord(f, 0) * Cos(f * pi180) - temrecord(j, 0) * Cos(j * pi180)))
csy = Int((basicrecord(f, 0) * Sin(f * pi180) - temrecord(j, 0) * Sin(j * pi180)))
count = 0
For k = 0 To 360
cangle = (k + 90) * pi180
cx = (temrecord(k, 0)) * Sin(cangle) + csx
cy = (temrecord(k, 0)) * Cos(cangle) + csy
jl = Sqr((cx - temrecord2(1, 0)) ^ 2 + (cy - temrecord2(1, 1)) ^ 2)
If jl > Val(Text7.Text) Then
count = count + 1
End If
If count > 180 Then Exit For
Next
DoEvents
Next
Next
Next
就这些运算,要完成就需要差不多20个小时,根本无法接受~
请问还能提高运算效率吗?
要如何改呢?
[解决办法]
csx = Int((basicrecord(f, 0) * Cos(f * pi180) - temrecord(j, 0) * Cos(j *
csy = Int((basicrecord(f, 0) * Sin(f * pi180) - temrecord(j, 0) * Sin(j *
这两句里面的
(basicrecord(f, 0) * Cos(f * pi180)和
(basicrecord(f, 0) * Sin(f * pi180)
属于重复计算,完全可以把这部分放到j循环外面
temrecord(k, 0))也一样
[解决办法]
你的循环嵌套太多,内层又有大量的浮点乘法、三角函数。
①至少有一个优化方案是:
把 0°~ 360°的正弦、余弦函数值预先处理,分别对应保存在一个 Double 类型的、下标为 0~360 的一维数组中,使用时直接以度数为下标,在数组中取值。
这个方法应该能大大提高速度。
②你的变量声明方式不正确。产生了大量的 Variant 类型的变量,这很影响速度。
③建议所有的变量,整数类型的都用 Long;Single 类型的都用 Double 。
特别是 Single 类型,可能很多人都不知道:在VB中,即使只有 Single 类型的数据参与运算,运算时也要先全部转换成 Double ,运算后再将结果转换成 Single 来赋值(当然赋值给 Double 类型的变量就不会再转了)。
④9F 的第一项。
[解决办法]
你会用API吗? 找一个图形旋转的API就搞定了,还算什么?
'================== 旋转图形用 ========================================
Public Type POINTS2D
X As Long
Y As Long
End Type
Public Const NotPi = 3.14159265238 / 180 '每度的弧度数
Public Const Pi = 3.14159265238
Public Declare Function PlgBlt Lib "gdi32" (ByVal hdcDest As Long, lpPoint As POINTS2D, _
ByVal hdcSrc As Long, ByVal nXSrc As Long, _
ByVal nYSrc As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal hbmMask As Long, _
ByVal xMask As Long, ByVal yMask As Long) As Long
Sub D中心转(ByRef picDestHdc As Long, xPos As Long, yPos As Long, Fd As Single, _
ByVal Angle As Long, ByRef picSrcHdc As Long, _
srcXoffset As Long, srcYoffset As Long, _
ByVal srcWidth As Long, ByVal srcHeight As Long)
' picDestHdc: 目标, xPos、yPos 中心坐标
' Fd 放大倍数 Angle 旋转角度
' srcYoffset: 源图,srcXoffset、srcYoffset、srcWidth、srcHeight 矩形范围
Dim points(3) As POINTS2D
Dim DefPoints(3) As POINTS2D
Dim ThetS As Single, ThetC As Single
Dim Ret As Long
points(0).X = -srcWidth * 0.5 * Fd
points(0).Y = -srcHeight * 0.5 * Fd
points(1).X = points(0).X + srcWidth * Fd
points(1).Y = points(0).Y
points(2).X = points(0).X
points(2).Y = points(0).Y + srcHeight * Fd
ThetS = Sin(Angle * NotPi)
ThetC = Cos(Angle * NotPi)
DefPoints(0).X = (points(0).X * ThetC - points(0).Y * ThetS) + xPos
DefPoints(0).Y = (points(0).X * ThetS + points(0).Y * ThetC) + yPos
DefPoints(1).X = (points(1).X * ThetC - points(1).Y * ThetS) + xPos
DefPoints(1).Y = (points(1).X * ThetS + points(1).Y * ThetC) + yPos
DefPoints(2).X = (points(2).X * ThetC - points(2).Y * ThetS) + xPos
DefPoints(2).Y = (points(2).X * ThetS + points(2).Y * ThetC) + yPos
PlgBlt picDestHdc, DefPoints(0), picSrcHdc, srcXoffset, srcYoffset, _
srcWidth, srcHeight, 0, 0, 0
End Sub
[解决办法]
'(一个窗体,上面两个按钮、一个标签)
Option Explicit
Private Sub Command1_Click()
Dim i&, Q&, n&, t#
t = Timer()
n = 4506
For i = 1 To 15000000
Q = n ^ 2
Next
Label1.Caption = Timer() - t
End Sub
Private Sub Command2_Click()
Dim i&, Q&, n&, t#
t = Timer()
n = 4506
For i = 1 To 15000000
Q = n * n
Next
Label1.Caption = Timer() - t
End Sub