读书人

拔高VB运行速度

发布时间: 2013-01-08 14:02:14 作者: rapoo

提高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









[解决办法]

引用:
引用:
所有的 X ^2 都改成 X*X
也能大大提高速度。

请问为何这个会提高速度?

首先你要明白,编译系统不是绝对聪明的,我相信它不会把 X^2 转换成 X*X。
你既然用的幂运算符,它就会按幂运算的方式来计算这个表达式。
幂如何运算?CPU能直接进行幂运算吗?
不能!秘密就是自然对数的底 e !!!

你可以试一下简单的测试:
'(一个窗体,上面两个按钮、一个标签)
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


指数运算耗时是乘法运算的100倍左右。

引用:
...........
点哪里啊?你用的什么输入法?

我常用的智能陈桥。
要进行特殊的输入时,切换到王码五笔或全拼就可以了,它有软键盘,在上面点鼠标右键......

[解决办法]
引用:
引用:
vb 要想速度快需要把握几个最最基本的原则:
㈠ 正确的变量声明,能使integer型就不要用long型,能使long型就不double
㈡ 尽量采用低级运算,如可以提前拆分的能加减不乘除,虽然这样会在写公式前算一下,不过会提高速度
㈢ 正确的或优化的算法

第一条前半部分是错误的
在32位操作系统上,4字节的long型变量是最快的
所以,应该是“能使用long就不适用integer”


“能使用long就不用integer”
这个是真的吗?我的计算程序可以全部更换了。

从这个帖子学到了很多。
[解决办法]
回63楼
参看MSDN“代码优化”部分:

使用 Long 整型变量和整数运算
算术运算中要避免使用 Currency、Single 和 Double 变量;并尽量使用 Long 整型变量,尤其在循环体中。因为 Long 整数是 32 位 CPU 的本机数据类型,所以其操作非常快;如果无法使用 Long 变量,就要尽量使用 Integer 或 Byte 数据类型。很多时候,即使在要求使用浮点数的情况下,也可以使用 Long 整数。例如,在窗体和图形控件的 ScaleMode 属性设置为缇或象素时,就可以在控件和图形方法中使用 Long 整型变量表示大小和位置。

进行除法运算时,如果不需要小数部分,就可以使用整数除法运算符 (/)。由于浮点运算需要转移到协处理器上进行,而整数运算并不需要,所以整数运算总是比浮点运算快。如果确实需要做小数运算,则 Double 数据类型比 Currency 数据类型快。

下表把各种数值数据类型按运算速度顺序列出。

数值数据类型 速度
Long 最快
Integer .

Byte .

Single .

Double .

Currency 最慢

[解决办法]


重复计算太多!

temp=(temrecord(k, 0) / maxv / 10)

sin 与 cos 是有关系的,变成一个运算。

If i - l < 0 Then
temrecord(i, 0) = record(i - l + 360, 0)
Else
temrecord(i, 0) = record(i…

想一下概率吧!那个该放前面减少判断。
[解决办法]

楼主的算法思路是否这样的:将一幅图旋转某一角度,与另一幅图比对?

其实应该分两阶段来做:
1 首先选取 A 图几个点,做旋转映射,与 B 图比对。算一个,比一个,有一个不同,就跳出到下一个角度。只有全部相同,才进入下一步。
2 对你做相同判断所需的所有点,做旋转映射和比对。只要有一个不同,就跳出到下一个角度。

也许要更好的算法,不需要这样一一比对。另外,如果 B 图是 A 图非整数角度的旋转映射,又怎么办?

读书人网 >VB

热点推荐