我正在使用内存扫描仪,但扫描速度很慢..任何人都可以帮我改进吗?
procedure FirstScan(scantype, scanvalue: string);
var
value :integer;
dwEndAddr : dword;
i:dword;
mbi : TMemoryBasicInformation;
begin
while (VirtualQuery(Pointer(DWORD(mbi.BaseAddress) + MBI.RegionSize), MBI, SizeOf(MEMORY_BASIC_INFORMATION))=SizeOf(TMemoryBasicInformation)) do begin
if (MBI.State = MEM_COMMIT) and (MBI.Protect = PAGE_READWRITE) then begin
dwEndAddr := DWORD(mbi.BaseAddress) + MBI.RegionSize;
for i := DWORD(MBI.BaseAddress) to (dwEndAddr - 1 - sizeof(DWORD)) do begin
Application.ProcessMessages;
try
if scantype = '1 Byte' then begin
value := PBYTE(i)^;
if scanvalue = IntToStr(value) then ListBox1.Items.Add(IntToHex(i,8));
end;
//others scantypes here...
except
Break;
end;
end;
end;
end;
end;
我已经知道我需要一次读取4096个字节的页面然后将它们存储在内存中并对其进行操作,直到我需要一个新的页面然后再获得另一个4096字节的页面......
但我不知道我该怎么做......
任何人都能帮助我吗?代码可以是C或C ++ ......
答案 0 :(得分:10)
我可以帮助你......从内循环中获取Application.ProcessMessages
。你是为每个人打电话的。单。字节。您。扫描。您不需要完全 响应窗口消息。 :)
将其向上移动到外部循环中,您应该会看到显着的速度增加。我会说产生一个线程并完全摆脱Application.ProcessMessages
,因为这不是代码的工作,但我不确定Delphi是如何做线程的。
另外....你将扫描参数作为字符串传递?如果您坚持这样做,请在开始循环之前设置int或enum或其他内容,以说明要使用的扫描类型,将值转换为有用的搜索类型,并进行比较。字符串比较往往比整数比较慢,特别是每次创建新字符串时。
答案 1 :(得分:8)
要快速制作慢速代码,您可以执行一些操作。首先,确保您的代码正确。错误的结果仍然是错误的结果,即使你很快得到它们。为此,请确保在致电VirtualQuery
时,您传递了所有参数的有效值。在此功能开始时mbi
未初始化,因此DWORD(mbi.BaseAddress) + MBI.RegionSize
的结果将是谁知道什么。
正确使用代码后,有两种方法可以加快代码:
找到缓慢的部分,让它们快速。要做到这一点,你需要一个分析器。分析器将在程序运行时观察您的程序,然后告诉您程序执行每个部分所花费的时间百分比。这告诉你在哪里集中精力。
用更快的算法替换慢速算法。这可能意味着丢掉整个函数,或者可能意味着只修复代码的某些部分。
例如,分析可能会显示您花了很多时间来调用ProcessMessages
。由于它是VCL的一部分,你无法更快地完成该功能,但是你可以更少地调用它。如果您运行此代码的线程不希望收到任何需要处理的消息,您甚至可能发现根本不需要调用它。
分析可能表明您花了很多时间进行字符串比较。如果字符串的开始经常相等,并且通常只在结尾处有所不同,那么您可能希望更改字符串比较算法以开始比较最后一个字符而不是第一个字符串。< / p>
分析可能表明您在比较它们之前花费了大量时间将整数转换为字符串。大多数编程语言都支持直接比较整数,因此您可以尝试使用整数比较算法,而不是使用字符串比较算法。您可以将scanvalue
转换为StrToInt(scanvalue)
的整数,并将其直接与value
进行比较。
分析可能表明您是从同一输入重复计算相同的结果。如果某个程序的某些部分的值没有变化,那么从它计算的值也不会改变。只有在值发生更改时,才能降低转换值的成本。例如,如果进行整数比较,那么您可能会发现scanvalue
的整数版本在您的函数中没有变化。你可以在函数开始时将scanvalue
转换为整数一次,然后将value
与循环内的整数进行比较,而不是多次调用StrToInt(scanvalue)
。
答案 2 :(得分:1)
另外:您正在将当前指针转换为您访问的每个字节的字符串。 Yech,非常慢。相反,在程序开始时将scanvalue更改为BYTE,并直接在BYTE上进行比较。
最后 - 从for i:= DWORD(MBI.BaseAddress)循环中拉出“if scantype ='1 byte'”。您不希望为每个字节执行“if”语句 - 而是执行
if scantype = '1 byte' then
for i:= DWORD(...)
else if scantype='other scan type' then...
等等。 (是的,你应该将“如果scantype”与enum或whatnot进行比较。)