首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

拔高VB运行速度

2013-01-08 
提高VB运行速度下面是我的代码:Dim temrecord2(360, 1) As LongDim i, j, k, l, f As IntegerDim count As

提高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 图非整数角度的旋转映射,又怎么办?

热点排行