为何 Call DLL 慢很多, 如何让他变快呢

bobogg 2014-09-25 09:44:49


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


Sub Form_Load
dim w as long

For W = 1 To 1000万转
Call timeGetTime --> 0.22 秒
Next

For W = 1 To 1000万转
Call QQQ --> 0.035 秒
Next


End Sub

Sub QQQ
.....................
End Sub



请问

(1) 为何 Call DLL 慢很多, 是什么原因呢.
(2) 有其他调用方式让他变快吗
...全文
249 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
好几天都把你剁了。结贴,半年了。 vb本来就是解析型的,你和其他语言去比怎么比得过 如果涉及到一些,大量的计算,或者是图像处理,那肯定要用c或者其他语言。 一般情况下,delphi和c的速度差不多。 最慢的是那个易语言
bobogg 2014-10-02
  • 打赏
  • 举报
回复
引用 9 楼 xiaoyao961 的回复:
Private Declare Function timeGetTime Lib "winmm.dll" () As Long Sub Form_Load dim w as long For W = 1 To 1000万转 Call timeGetTime --> 0.22 秒 Next 你不要拿这个timeGetTime 去比较,这个东西本身里面就包含了很多算法,肯定要CPU时间。 你自已用VB写一个空的标准DLL(如何用VB写标准DLL你自已另外看),里面含一个timeGetTime 这个函数,无代码,你再试下速度比较。timeGetTime ,无代码,无参数。纯SUB,不要FUNCTION. 也可以用C或别的语言写一个空的DLL,主要是怕VB的DLL又中间经过多重转换,也会影响速度。可以用CallWindowProc等方法进行内存地址的CALL
For W = 1 To 1000万转 Call timeGetTime Next VB --> 0.22 秒 Delphi --> 0.03 秒 所以慢肯定是 VB 编译器的问题 因为 delphi 只要 0.03 秒
  • 打赏
  • 举报
回复
只是说这个原理,但你要比速度的话还是不能用 GetProcAddress(lb, "DllRegisterServer"),因为这个也是需要单步就花不少时间的。你还是得弄一个空函数,也许,最快的方法就是JMP之类 吧
  • 打赏
  • 举报
回复
Option Explicit '模块名称:mdlRegServer '模块功能:不使用regServer.exe 来注册ActiceX OCX ,DLL '作者:softboy@263.net 从APIGUIDE整理得来 '更新日期:2003-7-29 7:59:58 PM '相关模块: '相关文件: '预期读者和阅读建议: '使用方法: ' 注册 RegisterServer Me.hWnd, "c:\somedir\some.ocx", True ' 注消 RegisterServer Me.hWnd, "c:\somedir\some.ocx", False Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) As Long Private Const ERROR_SUCCESS = &H0 Public Function RegisterServer(hWnd As Long, DllServerPath As String, bRegister As Boolean) On Error Resume Next '*关键外部调用:FileExist If Not mdlUtilities.FileExist(DllServerPath) Then MsgBox "Err: Cann't find the path [" & DllServerPath & "] !" Exit Function End If '*************** Dim lb As Long, pa As Long lb = LoadLibrary(DllServerPath) If bRegister Then pa = GetProcAddress(lb, "DllRegisterServer") Else pa = GetProcAddress(lb, "DllUnregisterServer") End If '*************** If CallWindowProc(pa, hWnd, ByVal 0&, ByVal 0&, ByVal 0&) = ERROR_SUCCESS Then MsgBox IIf(bRegister = True, "Registration", "Unregistration") + " Successful" Else MsgBox IIf(bRegister = True, "Registration", "Unregistration") + " Unsuccessful" End If '*************** FreeLibrary lb End Function '*********************************************************** '*希望能够对你有所帮助! '*********************************************************** 像这这个是一个直接调用DLL的方式 pa = GetProcAddress(lb, "DllRegisterServer"),然后FOr i=1 TO 1000万:call CallWindowProc(pa, hWnd, ByVal 0&, ByVal 0&, ByVal 0&)
  • 打赏
  • 举报
回复
Private Declare Function timeGetTime Lib "winmm.dll" () As Long Sub Form_Load dim w as long For W = 1 To 1000万转 Call timeGetTime --> 0.22 秒 Next 你不要拿这个timeGetTime 去比较,这个东西本身里面就包含了很多算法,肯定要CPU时间。 你自已用VB写一个空的标准DLL(如何用VB写标准DLL你自已另外看),里面含一个timeGetTime 这个函数,无代码,你再试下速度比较。timeGetTime ,无代码,无参数。纯SUB,不要FUNCTION. 也可以用C或别的语言写一个空的DLL,主要是怕VB的DLL又中间经过多重转换,也会影响速度。可以用CallWindowProc等方法进行内存地址的CALL
startbin 2014-09-28
  • 打赏
  • 举报
回复
想要速度快 准备一个sub和copymemory定义一样 然后修改sub的函数地址指向copymemory 这样调用这个sub 等于调用copymemory 绕过了vb调用api的机制会快速不少
  • 打赏
  • 举报
回复
timeGetTime ,如果你把这个DLL在你进程中的内存地址直接进行CALL的话也许速度是差不多的,假如你把Sub QQQ ..................... End Sub ,这个做成一个DLL,然后调用 Private Declare SUB QQQ Lib "MYDLL.dll" () ,你这样调用QQQ,可能还比较费时,如果你找出内存地址,应该会速度差不多了
bobogg 2014-09-28
  • 打赏
  • 举报
回复
引用 6 楼 startbin 的回复:
想要速度快 准备一个sub和copymemory定义一样 然后修改sub的函数地址指向copymemory 这样调用这个sub 等于调用copymemory 绕过了vb调用api的机制会快速不少
Thank you ! 不会写呢 有范例可参考吗?
bobogg 2014-09-28
  • 打赏
  • 举报
回复
引用 5 楼 xiaoyao961 的回复:
如果你找出内存地址
请问找出内存地址会用到哪些 WinAPI 的名称 [quote=引用 6 楼 startbin 的回复:] Thank you ! 不会写呢 有范例可参考吗?
bobogg 2014-09-27
  • 打赏
  • 举报
回复
引用 3 楼 sysdzw 的回复:
楼主这是要做什么呢?如果会被大量重复调用的话,能力范围内考虑使用vb原生的东西解决
hi~ Private Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) 我要用大量使用 CopyMemory 这个 VB6 没有原生的
无·法 2014-09-26
  • 打赏
  • 举报
回复
楼主这是要做什么呢?如果会被大量重复调用的话,能力范围内考虑使用vb原生的东西解决
bcrun 2014-09-26
  • 打赏
  • 举报
回复
怎么我觉得并不奇怪呢?
一如既往哈 2014-09-25
  • 打赏
  • 举报
回复
尽量避免在长(大)循环中使用耗时的操作

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧