这样子!我是这样子写的。按你的思路我应该更改哪里才能提高速度 fromlist有900W条,tolist有25W条 ,由于两个列表都已经排序,所以想到不从头历到尾 kmin:=0; while leftstr(fromlist[kmin],4)<>leftstr(tolist[0],4) do kmin:=Kmin+1; kmax:=fromlist.Count-1; while leftstr(fromlist[kmax],4)<>leftstr(tolist[tolist.Count-1],4) do kmax:=Kmax-1; For k:=kmax downto kmin do begin if tolist.IndexOf(fromlist[k])<>-1 then begin//在这里应该用POS吗? fromlist.Delete(k); s:=s+1; end; gg.Progress:=s; sb.Panels[3].Text:=inttostr(s); end;
这样,用两个stringlist载入,没问题的。 在第一个字符串列表 后边加A 在第二个字符串列表 后面加B 合成一个字符串列表 排序,从后往前遍历,如果上一个字符串A或B前的字符串,与下一个字符串A或B前的字符串形同,删除。 再把字符串列表分开保存还可以: 在一个用两个字符串列表分别载入,字符串是比较大小的,可以是S1>S2 这样的 sl1,sl2:tstringlist; i1,i2,n:integer; begin if i1>i2 n:=i1 else n:=i2; for i=0 to n-1 do being if sl[i1]<sl[i2] then i1=i1+1; if sl[i1]>sl[i2] then i2=i2+1; if sl[i1]=sl[i2] then begin sl[i2].delete; i1=i1+1; i2=i2+1; end; end; end;别用IndexOf,会慢死。
先发几个函数,后面的明天再发。function LoadTxtToMemory(FileName: string): TResult; const NEWSIZE = 1024 * 128; //128K var _FileMapHandle, _hFile: THandle; _Size, i, j, _LSize: Cardinal; _MapFile: Pointer; begin Result.Data := nil; _hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE or FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_READONLY, 0); _Size := GetFileSize(_hFile, 0); _FileMapHandle := CreateFileMapping(_hFile, nil, PAGE_READONLY, 0, 0, nil); _MapFile := MapViewOfFile(_FileMapHandle, FILE_MAP_READ, 0, 0, 0); ReallocMem(Result.Data, _Size); //申请空间 ZeroMemory(Result.Data, _Size); _LSize := _Size; i := 0; Result.Row := 0; while i < _Size do begin j := 0; while (PWORD(DWORD(_MapFile) + i + j)^ <> $0A0D) do begin Inc(j); if (i + j >= _Size) then Break; end; if (Result.Row * 128) >= _LSize then begin ReallocMem(Result.Data, _LSize + NEWSIZE); //申请空间 ZeroMemory(Pointer(DWORD(Result.Data) + (Result.Row * 128)), NEWSIZE); _LSize := _LSize + NEWSIZE; end; CopyMemory(Pointer(DWORD(Result.Data) + (Result.Row * 128)), Pointer(DWORD(_MapFile) + i), j); i := i + j + 2; inc(Result.Row); //行数 end; Inc(Result.Row); UnmapViewOfFile(_MapFile); _MapFile := nil; CloseHandle(_FileMapHandle); CloseHandle(_hFile); end;
procedure TForm1.Button1Click(Sender: TObject); var _Src, _Dest: TResult; _ResultList: TStringList; i: Cardinal; begin OpenDialog1.Title := '选择FormList...'; if OpenDialog1.Execute then begin OpenDialog1.Title := '选择ToList...'; _Src := LoadTxtToMemory(OpenDialog1.FileName); if OpenDialog1.Execute then begin _Dest := LoadTxtToMemory(OpenDialog1.FileName); if (_Src.Row < 1) or (_Dest.Row < 1) then exit; SSECmpText(_Src, _Dest); _ResultList := TStringList.Create; try _ResultList.Clear; for I := 0 to _Src.Row - 1 do begin if PDWORD(DWORD(_Src.Data) + (i * $80))^ <> $FFFFFFFF then //不相同输出 begin if CheckBox1.Checked then Memo1.Lines.Add(PChar(DWORD(_Src.Data) + (i * $80))) else _ResultList.Add(PChar(DWORD(_Src.Data) + (i * $80))); end; end; if _ResultList.Count > 0 then _ResultList.SaveToFile('.\ResultList.txt'); finally FreeAndNil(_ResultList); end; end; end; end;
这样子!我是这样子写的。按你的思路我应该更改哪里才能提高速度 fromlist有900W条,tolist有25W条 ,由于两个列表都已经排序,所以想到不从头历到尾 kmin:=0; while leftstr(fromlist[kmin],4)<>leftstr(tolist[0],4) do kmin:=Kmin+1; kmax:=fromlist.Count-1; while leftstr(fromlist[kmax],4)<>leftstr(tolist[tolist.Count-1],4) do kmax:=Kmax-1; For k:=kmax downto kmin do begin if tolist.IndexOf(fromlist[k])<>-1 then begin//在这里应该用POS吗? fromlist.Delete(k); s:=s+1; end; gg.Progress:=s; sb.Panels[3].Text:=inttostr(s); end;
http://topic.csdn.net/u/20100327/22/0b5656cb-f2c7-49c5-931c-1bd639ace04d.html
1。打开A, B两个文件
2。对两个文件排序
3。比较两个文件
4。在比较窗口中,点击选中A文件,
5。在比较窗口的工具栏中,点按纽“拷贝所有不同的行”,这将把所有和B文件不同的行拷贝到剪贴板
用PilotEdit就可以了。先謝謝你!最先測試,打開200M就花不少時間。不過濾160M。只過濾2500000行(不到6M)。就一直假死,不可取!
先謝過了,
我沒用過哈希,所以搜索了下相關的知識,找到delphi有相關的哈希函數,THashedStringList,TStringHash不知具體使用時有什麼技巧。用歷遍A,用IndexOf檢索效率相對TSTRINGLIST要高些,但我想應該有更高效的方法TStringHash這個具體不知如何用
謝謝哦,經測試在POS與indexof對比之下,後者明顯優於前者
Thanks
對比!非線程中的。假死應該是正常的打開200M就花不少時間。不過濾160M。只過濾25W行(不到6M),對比,前面我寫到250W,是錯誤但不能再編輯
1。读B文件,
2。把B文件中的行放入一个hash表中(表的size尽可能大一些)
3。读A文件并把每行到hash表中匹配,如果没有,就输入结果文件中你坐下来,1-3步,大约每步花了多少分钟?(总时间是117分钟)
哪步慢就改进那一步。
第二种就是代码级的优化。下面大概写了算法,使用了SIMD指令:Mov esi,src
Mov edi,dest
Mov ebx,ptmp //size 64byte
@loop:
//读入A一行128byte
xorps xmm0,xmm0
movups xmmword ptr [ebx], xmm0
movups xmm0, xmmword ptr [esi]
movups xmm1, xmmword ptr [esi+$10]
movups xmm2, xmmword ptr [esi+$20]
movups xmm3, xmmword ptr [esi+$30]
movups xmm4, xmmword ptr [esi+$40]
movups xmm5, xmmword ptr [esi+$50]
movups xmm6, xmmword ptr [esi+$60]
movups xmm7, xmmword ptr [esi+$70]//与B一行 xor
xorps xmm0, xmmword ptr [edi]
xorps xmm1, xmmword ptr [edi+$10]
xorps xmm2, xmmword ptr [edi+$20]
xorps xmm3, xmmword ptr [edi+$30]
xorps xmm4, xmmword ptr [edi+$40]
xorps xmm5, xmmword ptr [edi+$50]
xorps xmm6, xmmword ptr [edi+$60]
xorps xmm7, xmmword ptr [edi+$70]//判断是否全相等
xorps xmmword ptr [ebx],xmm0
xorps xmmword ptr [ebx],xmm1
xorps xmmword ptr [ebx],xmm2
xorps xmmword ptr [ebx],xmm3
xorps xmmword ptr [ebx],xmm4
xorps xmmword ptr [ebx],xmm5
xorps xmmword ptr [ebx],xmm6
xorps xmmword ptr [ebx],xmm7
Xor eax,eax
Cmp eax,[ebx]
Cmp eax,[ebx+4]
Cmp eax,[ebx+8]
Cmp eax,[ebx+$C]
//判断后这里可以处理如果[ebx]16byte全0则代表两行相同
//…..
Add esi,$80 //下一行
Add edi,$80
Cmp esi,endlen
Jnz loop
Cmp edi,endlen
Jnz loop
分两种优化,1种是逻辑上算法的优化,一般最后都需要对比两段字串是否相同而这个操作是最耗费时间的
第二种就是代码级的优化。下面大概写了算法,使用了SIMD指令:太對不住了,給我寫這麼多代碼,我卻消化不了。这是汇编吗?
fromlist有900W条,tolist有25W条 ,由于两个列表都已经排序,所以想到不从头历到尾
kmin:=0;
while leftstr(fromlist[kmin],4)<>leftstr(tolist[0],4) do
kmin:=Kmin+1; kmax:=fromlist.Count-1;
while leftstr(fromlist[kmax],4)<>leftstr(tolist[tolist.Count-1],4) do
kmax:=Kmax-1; For k:=kmax downto kmin do begin
if tolist.IndexOf(fromlist[k])<>-1 then begin//在这里应该用POS吗?
fromlist.Delete(k);
s:=s+1;
end;
gg.Progress:=s;
sb.Panels[3].Text:=inttostr(s);
end;
在第一个字符串列表 后边加A
在第二个字符串列表 后面加B
合成一个字符串列表
排序,从后往前遍历,如果上一个字符串A或B前的字符串,与下一个字符串A或B前的字符串形同,删除。
再把字符串列表分开保存还可以:
在一个用两个字符串列表分别载入,字符串是比较大小的,可以是S1>S2 这样的
sl1,sl2:tstringlist;
i1,i2,n:integer;
begin
if i1>i2 n:=i1 else n:=i2;
for i=0 to n-1 do
being
if sl[i1]<sl[i2] then i1=i1+1;
if sl[i1]>sl[i2] then i2=i2+1;
if sl[i1]=sl[i2] then
begin
sl[i2].delete;
i1=i1+1;
i2=i2+1;
end;
end;
end;别用IndexOf,会慢死。
这样,用两个stringlist载入,没问题的。
在第一个字符串列表 后边加A
在第二个字符串列表 后面加B
合成一个字符串列表
排序,从后往前遍历,如果上一个字符串A或B前的字符串,与下一个字符串A或B前的字符串形同,删除。
再把字符串列表分开保存
======================
非常感谢!这个主意感觉不错!马上测试
第二种就是代码级的优化。下面大概写了算法,使用了SIMD指令:
Delphi(Pascal) code
Mov esi,src
Mov edi,dest
Mov ebx,ptmp //size 64byte
@loop:
//读入A一行128byte
xorps xmm0,xmm0
movups xmmword ptr [ebx], xmm0
movups xmm0, xmmword ptr [esi]
movups xmm1, xmmword ptr [esi+$10]
movups xmm2, xmmword ptr [esi+$20]
movups xmm3, xmmword ptr [esi+$30]
movups xmm4, xmmword ptr [esi+$40]
movups xmm5, xmmword ptr [esi+$50]
movups xmm6, xmmword ptr [esi+$60]
movups xmm7, xmmword ptr [esi+$70]//与B一行 xor
xorps xmm0, xmmword ptr [edi]
xorps xmm1, xmmword ptr [edi+$10]
xorps xmm2, xmmword ptr [edi+$20]
xorps xmm3, xmmword ptr [edi+$30]
xorps xmm4, xmmword ptr [edi+$40]
xorps xmm5, xmmword ptr [edi+$50]
xorps xmm6, xmmword ptr [edi+$60]
xorps xmm7, xmmword ptr [edi+$70]//判断是否全相等
xorps xmmword ptr [ebx],xmm0
xorps xmmword ptr [ebx],xmm1
xorps xmmword ptr [ebx],xmm2
xorps xmmword ptr [ebx],xmm3
xorps xmmword ptr [ebx],xmm4
xorps xmmword ptr [ebx],xmm5
xorps xmmword ptr [ebx],xmm6
xorps xmmword ptr [ebx],xmm7
Xor eax,eax
Cmp eax,[ebx]
Cmp eax,[ebx+4]
Cmp eax,[ebx+8]
Cmp eax,[ebx+$C]
//判断后这里可以处理如果[ebx]16byte全0则代表两行相同
//…..
Add esi,$80 //下一行
Add edi,$80
Cmp esi,endlen
Jnz loop
Cmp edi,endlen
Jnz loop
const
NEWSIZE = 1024 * 128; //128K
var
_FileMapHandle, _hFile: THandle;
_Size, i, j, _LSize: Cardinal;
_MapFile: Pointer;
begin
Result.Data := nil;
_hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE or FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_READONLY, 0);
_Size := GetFileSize(_hFile, 0);
_FileMapHandle := CreateFileMapping(_hFile, nil, PAGE_READONLY, 0, 0, nil);
_MapFile := MapViewOfFile(_FileMapHandle, FILE_MAP_READ, 0, 0, 0);
ReallocMem(Result.Data, _Size); //申请空间
ZeroMemory(Result.Data, _Size);
_LSize := _Size;
i := 0;
Result.Row := 0;
while i < _Size do
begin
j := 0;
while (PWORD(DWORD(_MapFile) + i + j)^ <> $0A0D) do
begin
Inc(j);
if (i + j >= _Size) then Break;
end;
if (Result.Row * 128) >= _LSize then
begin
ReallocMem(Result.Data, _LSize + NEWSIZE); //申请空间
ZeroMemory(Pointer(DWORD(Result.Data) + (Result.Row * 128)), NEWSIZE);
_LSize := _LSize + NEWSIZE;
end;
CopyMemory(Pointer(DWORD(Result.Data) + (Result.Row * 128)), Pointer(DWORD(_MapFile) + i), j);
i := i + j + 2;
inc(Result.Row); //行数
end;
Inc(Result.Row);
UnmapViewOfFile(_MapFile);
_MapFile := nil;
CloseHandle(_FileMapHandle);
CloseHandle(_hFile);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
_Src, _Dest: TResult;
_ResultList: TStringList;
i: Cardinal;
begin
OpenDialog1.Title := '选择FormList...';
if OpenDialog1.Execute then
begin
OpenDialog1.Title := '选择ToList...';
_Src := LoadTxtToMemory(OpenDialog1.FileName);
if OpenDialog1.Execute then
begin
_Dest := LoadTxtToMemory(OpenDialog1.FileName);
if (_Src.Row < 1) or (_Dest.Row < 1) then exit;
SSECmpText(_Src, _Dest);
_ResultList := TStringList.Create;
try
_ResultList.Clear;
for I := 0 to _Src.Row - 1 do
begin
if PDWORD(DWORD(_Src.Data) + (i * $80))^ <> $FFFFFFFF then //不相同输出
begin
if CheckBox1.Checked then
Memo1.Lines.Add(PChar(DWORD(_Src.Data) + (i * $80))) else
_ResultList.Add(PChar(DWORD(_Src.Data) + (i * $80)));
end;
end;
if _ResultList.Count > 0 then _ResultList.SaveToFile('.\ResultList.txt'); finally
FreeAndNil(_ResultList);
end;
end;
end;
end;
这么晚还在啊!代码都写全了,太感谢了!我再测试!
Delphi(Pascal) code=======================
直接对比内存这应该是最快的了可惜我还用D7,得先找个delphi2009安装才能测试
按照结构体的字数对数组排序,然后进行进行比较,先读取A的第一行,得到字数,然后便利B数组,如果有字数相等的B数组元素,再进行字符串比较,处理完A的第一行后处理第二行,对第二行的字数进行判断,然后和上一次比较时POS在B数组的位置,看大于等于还是小于,如果大于或小于,直接进行前进[或]者后退遍历B数组,如果等于,记住当前位置进行前进[和]后退的处理,找到相同数字的行进行字符串内容的比较,然后继续处理A之后的行,以此类推。
我数据结构学得也很烂,这个比较繁琐。但是和逐行比较,要快些。只是大概想法。
上班去了哈哈。
fromlist有900W条,tolist有25W条 ,由于两个列表都已经排序,所以想到不从头历到尾
kmin:=0;
while leftstr(fromlist[kmin],4)<>leftstr(tolist[0],4) do
kmin:=Kmin+1; kmax:=fromlist.Count-1;
while leftstr(fromlist[kmax],4)<>leftstr(tolist[tolist.Count-1],4) do
kmax:=Kmax-1; For k:=kmax downto kmin do begin
if tolist.IndexOf(fromlist[k])<>-1 then begin//在这里应该用POS吗?
fromlist.Delete(k);
s:=s+1;
end;
gg.Progress:=s;
sb.Panels[3].Text:=inttostr(s);
end;
思想:不是匹配,而是查找。
把最小的文本建立成trie树,然后用大文本的每一行去trie树中查找,遍历到叶子即表示A与B中有相同的行。
这种方法的查找是线性数组查找,速度非常快。每一行到另外一个文本中比较是最慢的办法,如果用hash运算的过程可能也不会太快。不过tire树是不平衡树,非常耗内存的,但速度非常快。
与你机子的配置就有一点关系了
就几百M又不是什么大文件
var
_FileMapHandle, _hFile: THandle;
_Size, i, j, k: Cardinal;
_MapFile: Pointer;
begin
Result.Data := nil;
_hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE or FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_READONLY, 0);
_Size := GetFileSize(_hFile, 0);
_FileMapHandle := CreateFileMapping(_hFile, nil, PAGE_READONLY, 0, 0, nil);
_MapFile := MapViewOfFile(_FileMapHandle, FILE_MAP_READ, 0, 0, 0);
i := 0;
Result.Row := 0;
while i < _Size do
begin
j := 0;
while (PWORD(DWORD(_MapFile) + i + j)^ <> $0A0D) do
begin
Inc(j);
if (i + j >= _Size) then Break;
end;
i := i + j + 2;
inc(Result.Row); //行数
end;
Result.Data := VirtualAlloc(nil, Result.Row * 128, MEM_COMMIT, PAGE_READWRITE);
ZeroMemory(Result.Data, Result.Row * 128);
i := 0;
k := 0;
while i < _Size do
begin
j := 0;
while (PWORD(DWORD(_MapFile) + i + j)^ <> $0A0D) do
begin
Inc(j);
if (i + j >= _Size) then Break;
end;
CopyMemory(Pointer(DWORD(Result.Data) + (k * 128)), Pointer(DWORD(_MapFile) + i), j);
i := i + j + 2;
Inc(k);
end;
UnmapViewOfFile(_MapFile);
_MapFile := nil;
CloseHandle(_FileMapHandle);
CloseHandle(_hFile);
end;procedure AsmCmpText(Src, Dest: TResult);
var
_Src, _Dest: Pointer;
_SRow, _DRow, _pSrc, _pDest: Cardinal;
begin
_Src := Src.Data;
_Dest := Dest.Data;
_SRow := Src.Row;
_DRow := Dest.Row;
asm
push esi
push edi
push ecx
push edx
push eax
push ebx
mov esi,_Src
mov edi,_Dest
mov _pSrc,esi
mov _pDest,edi
xor edx,edx //SrcRow
xor eax,eax //DestRow
@Loop1:
mov ecx,32
rep cmpsd
jnz @NextDest
mov ebx,_pSrc
mov [ebx],$FFFFFFFF //第Edx行相同处理
jmp @NextSrc @NextDest:
add eax,1
mov Edi,_pDest
mov esi,_pSrc
add edi,$80
mov _pDest,Edi
cmp eax,_DRow
jne @Loop1 @NextSrc:
xor eax,eax //DestRow
mov esi,_pSrc
mov Edi,_Dest
mov _pDest,edi
add esi,$80
mov _pSrc,esi
add edx,1
cmp edx,_SRow
jne @Loop1 pop ebx
pop eax
pop edx
pop ecx
pop edi
pop esi
end;end;procedure TForm1.Button1Click(Sender: TObject);
var
_Src, _Dest: TResult;
_ResultList: TStringList;
i, FormTime, ToTime, SSETiem, SaveTime: Cardinal;
SSECmp1, SSECmp2, SSECmp3, SSECmp4: TSSECmp;
_InputData: TInputData;
begin
OpenDialog1.Title := '选择FormList...';
if OpenDialog1.Execute then
begin
OpenDialog1.Title := '选择ToList...';
FormTime := GetTickCount;
_Src := LoadTxtToMemory(OpenDialog1.FileName);
FormTime := (GetTickCount - FormTime) div 1000;
Memo1.Lines.Add(Format('LoadFormTime:%d秒', [FormTime]));
if OpenDialog1.Execute then
begin
ToTime := GetTickCount;
_Dest := LoadTxtToMemory(OpenDialog1.FileName);
ToTime := (GetTickCount - ToTime) div 1000;
Memo1.Lines.Add(Format('LoadToTime:%d秒', [ToTime]));
if (_Src.Row < 1) or (_Dest.Row < 1) then exit;
SSETiem := GetTickCount;
_InputData.Dest := _Dest;
_InputData.Src.Data := Pointer(dword(_Src.Data));
_InputData.Src.Row := 1000000;
SSECmp1 := TSSECmp.Create(_InputData, false); _InputData.Dest := _Dest;
_InputData.Src.Data := Pointer(dword(_Src.Data) + (1000000 * 128));
_InputData.Src.Row := 1000000;
SSECmp2 := TSSECmp.Create(_InputData, false);
WaitForSingleObject(SSECmp2.Handle, INFINITE);
WaitForSingleObject(SSECmp1.Handle, INFINITE); SSETiem := (GetTickCount - SSETiem) div 1000;
Memo1.Lines.Add(Format('SSETiem:%d秒', [SSETiem]));
SaveTime := GetTickCount;
_ResultList := TStringList.Create;
try
_ResultList.Clear;
for I := 0 to _Src.Row - 1 do
begin
if PDWORD(DWORD(_Src.Data) + (i * $80))^ <> $FFFFFFFF then //不相同输出
begin
if CheckBox1.Checked then
Memo1.Lines.Add(PChar(DWORD(_Src.Data) + (i * $80))) else
_ResultList.Add(PChar(DWORD(_Src.Data) + (i * $80)));
end;
end;
if _ResultList.Count > 0 then _ResultList.SaveToFile('.\ResultList.txt');
SaveTime := (GetTickCount - SaveTime) div 1000;
Memo1.Lines.Add(Format('SaveTime:%d秒', [SaveTime]));
finally
FreeAndNil(_ResultList);
end;
end;
end;
end;function RandomStr(const sLen: Integer): string;
var
i, size: Integer;
s: string;
begin
Result := '';
Randomize;
if sLen < 5 then size := 5 else size := sLen;
s := 'Ae6STUnVWXYZopvw897tuHIJg3DEFGqabBCflmrs5cd4hijkKLMN012OPQRxyz';
for I := 0 to size - 1 do Result := Result + s[Random(Length(s) - 1) + 1];
end;procedure TForm1.Button2Click(Sender: TObject);
var
_List, _List2: TStringList;
i: integer;
begin
_List := TStringList.Create;
_List2 := TStringList.Create; for I := 1 to 5000 do
begin
Randomize;
_List.Add(RandomStr(Random(30)));
end; for I := 1 to 2000000 do
begin
Randomize;
_List2.Add(_List.Strings[Random(50)]);
end; _List2.SaveToFile('Form.txt');
_List2.Clear; for I := 1 to 250000 do
begin
Randomize;
_List2.Add(_List.Strings[Random(5000)]);
end;
_List2.SaveToFile('To.txt'); FreeAndNil(_List2);
FreeAndNil(_List);
end;
随机生成了formlist 200W条,ToList 25W条然后处理最快125秒 这个应该是极限了,排不排序对这算法没影响。
==========
這一定是最優的方法了!能不能直接發你的project給我測試下!我的delphi2010還在下載啊!我用分塊過濾,200W從過濾25W行。得花1到3分鐘。
我QQ:283221234,謝謝
不好意思!我的delphi7,還不支持TResult這東西, delphi下載一天了還沒完
type
TResult = packed record
Data: Pointer;
Row: Cardinal;
end; TInputData = packed record
Src: TResult;
Dest: TResult;
end;
_InputData.Src.Data := Pointer(dword(_Src.Data));
_InputData.Src.Row := 1000000;
SSECmp1 := TSSECmp.Create(_InputData, false); _InputData.Dest := _Dest;
_InputData.Src.Data := Pointer(dword(_Src.Data) + (1000000 * 128));
_InputData.Src.Row := 1000000;
SSECmp2 := TSSECmp.Create(_InputData, false);
WaitForSingleObject(SSECmp2.Handle, INFINITE);
WaitForSingleObject(SSECmp1.Handle, INFINITE);
是创建两个线程把formlist分2块进行过滤