首页
社区
课程
招聘
[求助]NT 和 ZW 和 其它的 API 调用为什么一样快
发表于: 2009-10-12 06:12 6537

[求助]NT 和 ZW 和 其它的 API 调用为什么一样快

2009-10-12 06:12
6537
下面代码试了多次, 差不多一样快, 不知为什么???
不是 ZW 的 API 快吗?

procedure TForm1.Button1Click(Sender: TObject);
var
  mTreeNode:TTreeNode;
  hheap:THandle;
  SYSTEM_PROCESSES_Info : PSYSTEM_PROCESSES;
  Ns:NTSTATUS;
  PN:string;
  i, J : integer;
  DT : TDateTime;
  FT : TFileTime;
  ST : TsystemTime;
  StartTime, EndTime:   integer;

begin
  for J:=0 to 500 do    // 调用 500 次 NtQuerySystemInformation
  begin
  StartTime:=GetTickCount;

  hheap:=GetProcessHeap;
  if hheap=0 then
  begin
    showmessage('Get Heap Error!');
    exit;
  end;
  SYSTEM_PROCESSES_Info:=HeapAlloc(hheap, HEAP_ZERO_MEMORY,BLOCK_SIZE);
  if SYSTEM_PROCESSES_Info = nil then
  begin
    showmessage('HeapAlloc error!');
    exit;
  end;
  i:=1;
  repeat
    Ns:=NtQuerySystemInformation(SystemProcessesAndThreadsInformation,  // 指定了所查询的系统信息类型
                                 SYSTEM_PROCESSES_Info, // 一个指针,这个指针用来返回系统句柄列表,在调用NtQuerySystemInformation函数之前,必须为这个指针分配足够的内存空间,否则函数调用会出错
                                 BLOCK_SIZE * i,  // 所分配的内存空间大小,单位是byte
                                 nil);  // 返回的大小
    if Ns=STATUS_INFO_LEN_MISMATCH then  // 如果函数调用成功,返回值将是0,否则可以使用GetLastError()获得详细的错误代码。
    begin
      inc(i);
      SYSTEM_PROCESSES_Info:=HeapReAlloc(hheap, HEAP_ZERO_MEMORY, SYSTEM_PROCESSES_Info, BLOCK_SIZE * i);
      if SYSTEM_PROCESSES_Info =nil then
      begin
        showmessage('HeapReAlloc error!');
        exit;
      end;
    end;
  until ns<>STATUS_INFO_LEN_MISMATCH;
  TreeView1.Items.Clear;
  repeat
    SYSTEM_PROCESSES_Info:=PSYSTEM_PROCESSES(dword(SYSTEM_PROCESSES_Info) + SYSTEM_PROCESSES_Info.NextEntryDelta);
    pn:=widechartostring(SYSTEM_PROCESSES_Info.ProcessName.buffer);
    mTreeNode:=TreeView1.Items.Add(nil, pn);
    treeview1.Items.AddChild(mTreeNode, '进程标识符:'+inttostr(SYSTEM_PROCESSES_Info.ProcessID));
    treeview1.Items.AddChild(mTreeNode, '父进程的标识符:'+inttostr(SYSTEM_PROCESSES_Info.InheritedFromProcessId));

  until SYSTEM_PROCESSES_Info.NextEntryDelta=0;
  end;
  EndTime:=GetTickCount;
  showmessage('总共花了 '+ Inttostr(EndTime-StartTime)+ ' ms');

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  mTreeNode:TTreeNode;
  hheap:THandle;
  SYSTEM_PROCESSES_Info : PSYSTEM_PROCESSES;
  Ns:NTSTATUS;
  PN:string;
  i, J : integer;
  DT : TDateTime;
  FT : TFileTime;
  ST : TsystemTime;
  StartTime, EndTime:   integer;

begin
  for J:=0 to 500 do  // 调用 500 次 ZWQuerySystemInformation
  begin
  StartTime:=GetTickCount;

  hheap:=GetProcessHeap;
  if hheap=0 then
  begin
    showmessage('Get Heap Error!');
    exit;
  end;
  SYSTEM_PROCESSES_Info:=HeapAlloc(hheap, HEAP_ZERO_MEMORY,BLOCK_SIZE);
  if SYSTEM_PROCESSES_Info = nil then
  begin
    showmessage('HeapAlloc error!');
    exit;
  end;

  i:=1;
  repeat
    Ns:=ZWQuerySystemInformation(SystemProcessesAndThreadsInformation,  // 指定了所查询的系统信息类型
                                 SYSTEM_PROCESSES_Info, // 一个指针,这个指针用来返回系统句柄列表,在调用NtQuerySystemInformation函数之前,必须为这个指针分配足够的内存空间,否则函数调用会出错
                                 BLOCK_SIZE * i,  // 所分配的内存空间大小,单位是byte
                                 nil);  // 返回的大小
    if Ns=STATUS_INFO_LEN_MISMATCH then  // 如果函数调用成功,返回值将是0,否则可以使用GetLastError()获得详细的错误代码。
    begin
      inc(i);
      SYSTEM_PROCESSES_Info:=HeapReAlloc(hheap, HEAP_ZERO_MEMORY, SYSTEM_PROCESSES_Info, BLOCK_SIZE * i);
      if SYSTEM_PROCESSES_Info =nil then
      begin
        showmessage('HeapReAlloc error!');
        exit;
      end;
    end;
  until ns<>STATUS_INFO_LEN_MISMATCH;
  TreeView1.Items.Clear;
  repeat
    SYSTEM_PROCESSES_Info:=PSYSTEM_PROCESSES(dword(SYSTEM_PROCESSES_Info) + SYSTEM_PROCESSES_Info.NextEntryDelta);
    pn:=widechartostring(SYSTEM_PROCESSES_Info.ProcessName.buffer);
    mTreeNode:=TreeView1.Items.Add(nil, pn);
    treeview1.Items.AddChild(mTreeNode, '进程标识符:'+inttostr(SYSTEM_PROCESSES_Info.ProcessID));
    treeview1.Items.AddChild(mTreeNode, '父进程的标识符:'+inttostr(SYSTEM_PROCESSES_Info.InheritedFromProcessId));
  until SYSTEM_PROCESSES_Info.NextEntryDelta=0;
  end;
  EndTime:=GetTickCount;
  showmessage('总共花了 '+ Inttostr(EndTime-StartTime)+ ' ms');
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  found : boolean;
  I, J : Integer;
  ProcessListHandle, modSnapShot : THandle;  //进程列表的句柄

  mProcess: TMODULEENTRY32;

  ProcessStruct : TProcessEntry32;
  mTreeNode:TTreeNode;
  StartTime, EndTime:   integer;

begin
  for J:=0 to 500 do  // 调用 500 次  CreateToolhelp32Snapshot
  begin
  StartTime:=GetTickCount;
  ProcessListHandle := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
  ProcessStruct.dwSize := Sizeof(ProcessStruct);
  found := Process32First(ProcessListHandle, ProcessStruct);
  I:=0;
  TreeView1.Items.Clear;
    with ProcessStruct do
    begin
      while found do
      begin
      mTreeNode:=TreeView1.Items.Add(nil, szExeFile);
      treeview1.Items.AddChild(mTreeNode, '进程标识符:'+inttostr(th32ProcessID));
      treeview1.Items.AddChild(mTreeNode, '父进程的标识符:'+inttostr(th32ParentProcessID));
      Inc(I);
      found:=Process32Next(ProcessListHandle, ProcessStruct);
      end; { while found do }
    end; { with ProcessStruct do }
  CloseHandle(ProcessListHandle);

  end;
  EndTime:=GetTickCount;
  showmessage('总共花了 '+ Inttostr(EndTime-StartTime)+ ' ms');
  //ViewProcessThread:=0;
end;

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
上面的差不多全是 16 MS
2009-10-12 06:13
0
雪    币: 226
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
**,自己反一下NTDLL.DLL里NT对应ZW的代码!
2009-10-14 00:24
0
雪    币: 962
活跃值: (1681)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
````````用 rdtsc 指令就能测出来了
2009-10-14 02:02
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不是 ZW 的 API 快吗?

不造谣,不传谣,不信谣
2009-10-14 09:20
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
6
1.次数太少,看不出差别
2.你自己的处理也有差别,不一样快也被你掩盖了
3.zw和nt在ntdll中是一样的
4.内核下nt比zw快一些
2009-10-14 15:20
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
晕啊, 上次我自已试过快3份一的,所以改用 NT 的 API,后来又想试多一次, 所以重新又写了一份, 原来写错了, 把 GetTickCount 放在 for 了,多谢大家提醒!!!

  在这里,特别多谢 qihoocom 了。
2009-10-15 04:20
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看调用的原理
至少其他的API比NT,ZW慢一点点是可能的
有些API需要调用NTDLL来实现自己 所以是种多层调用结构
快慢主要看代码长度……
2009-10-15 17:26
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
谢谢, 已解决!!!!!!!!!
2009-11-14 17:03
0
游客
登录 | 注册 方可回帖
返回
//