文本A 200M格式:
dsafdsafd
dsafdsafdsafdsa
dsafdsafdsa
dsafdsaf
.....
文本B 150M格式:相同用哪種方法將文本A中與文本B中相同的行過濾掉最好不要用什麼數據庫之類的

解决方案 »

  1.   

    如果不同行的也要KILL,那很简单的,比如要過濾掉B中的,可以把B中的分块(先读行数)存进TSTRINGLIST里(按行数存进划分,读入到TSTRINGLIST的ARRAY里),然后读一行A的,POS一下,有就KILL  {如果内存够大,可以不用ARRAY}
      

  2.   

    用PilotEdit就可以了。
    http://topic.csdn.net/u/20100327/22/0b5656cb-f2c7-49c5-931c-1bd639ace04d.html
    1。打开A, B两个文件
    2。对两个文件排序
    3。比较两个文件
    4。在比较窗口中,点击选中A文件,
    5。在比较窗口的工具栏中,点按纽“拷贝所有不同的行”,这将把所有和B文件不同的行拷贝到剪贴板
      

  3.   

    [Quote=引用 4 楼 pilotedit 的回复:]
    用PilotEdit就可以了。先謝謝你!最先測試,打開200M就花不少時間。不過濾160M。只過濾2500000行(不到6M)。就一直假死,不可取!
      

  4.   


    先謝過了,
    我沒用過哈希,所以搜索了下相關的知識,找到delphi有相關的哈希函數,THashedStringList,TStringHash不知具體使用時有什麼技巧。用歷遍A,用IndexOf檢索效率相對TSTRINGLIST要高些,但我想應該有更高效的方法TStringHash這個具體不知如何用
      

  5.   


    謝謝哦,經測試在POS與indexof對比之下,後者明顯優於前者 
      

  6.   

    请教一下搂主,是在做哪一步的时候出现假死?你大概等了多长时间?
    Thanks
      

  7.   

    [Quote=引用 8 楼 pilotedit 的回复:]
    對比!非線程中的。假死應該是正常的打開200M就花不少時間。不過濾160M。只過濾25W行(不到6M),對比,前面我寫到250W,是錯誤但不能再編輯
      

  8.   

    一般来说是如下步骤:
    1。读B文件,
    2。把B文件中的行放入一个hash表中(表的size尽可能大一些)
    3。读A文件并把每行到hash表中匹配,如果没有,就输入结果文件中你坐下来,1-3步,大约每步花了多少分钟?(总时间是117分钟)
    哪步慢就改进那一步。
      

  9.   

    请问每行有多长,都是char的字符吗?
      

  10.   

    提供个思路先A xor B 然后除掉空行
      

  11.   

    请问每行有多长,都是char的字符吗?
      

  12.   

    如果长度正好是2n次方长且不超过64byte或许有更块的算法
      

  13.   

    分两种优化,1种是逻辑上算法的优化,一般最后都需要对比两段字串是否相同而这个操作是最耗费时间的
    第二种就是代码级的优化。下面大概写了算法,使用了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
      

  14.   

    [Quote=引用 22 楼 codegame 的回复:]
    分两种优化,1种是逻辑上算法的优化,一般最后都需要对比两段字串是否相同而这个操作是最耗费时间的
    第二种就是代码级的优化。下面大概写了算法,使用了SIMD指令:太對不住了,給我寫這麼多代碼,我卻消化不了。这是汇编吗?
      

  15.   

    比较和数据吞吐上比一般的pos要高几个数量级,不过有个要求需要把你那两个文档处理成每段对齐128byte的
      

  16.   

    这样子!我是这样子写的。按你的思路我应该更改哪里才能提高速度
    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;
      

  17.   

    这样,用两个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,会慢死。
      

  18.   

    [Quote=引用 28 楼 yshuui 的回复:]
    这样,用两个stringlist载入,没问题的。
    在第一个字符串列表 后边加A
    在第二个字符串列表 后面加B
    合成一个字符串列表
    排序,从后往前遍历,如果上一个字符串A或B前的字符串,与下一个字符串A或B前的字符串形同,删除。
    再把字符串列表分开保存
    ======================
    非常感谢!这个主意感觉不错!马上测试
      

  19.   

    分两种优化,1种是逻辑上算法的优化,一般最后都需要对比两段字串是否相同而这个操作是最耗费时间的
    第二种就是代码级的优化。下面大概写了算法,使用了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
      

  20.   

    [Quote=引用 32 楼 diamondhands 的回复:]谢谢代码!
      

  21.   

    用正则表达式,如果觉得我回答的可以,就帮我看看我的淘宝客网站http://www.kkxxm.com,才上线,给点意见
      

  22.   

    我觉得还是该用二进制读取,然后分块,比如每块128KB,然后直接二进制对比,如果b文本中和a文本中数据顺序不一样,而且b文本较小,建议读入内存,然后超找-修改-输出,速度会快很多,中间可以生成个tmp文件我是用C++的,想来dephi也一样道理吧
      

  23.   

    先发几个函数,后面的明天再发。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;
      

  24.   


    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;
      

  25.   

    [Quote=引用 45 楼 codegame 的回复:]
    这么晚还在啊!代码都写全了,太感谢了!我再测试!
      

  26.   

    安装了ubuntu后,我迷迷糊糊滴登录了csdn,看到这个帖子我吓一跳:怎么还都变成繁体字了。后来仔细一看,并非如此。
      

  27.   

    1 用hash是可以,如果想要减少内存量,是否可以使用树来管理
      

  28.   

    [Quote=引用 45 楼 codegame 的回复:]
    Delphi(Pascal) code=======================
    直接对比内存这应该是最快的了可惜我还用D7,得先找个delphi2009安装才能测试
      

  29.   

    用FileMap或别的先读取文件到内存,将每行的字符数和每行字符串分别保存到某结构体(字数,字符串),放入数组,这些步骤在读取文件的时候也可以一起完成。
    按照结构体的字数对数组排序,然后进行进行比较,先读取A的第一行,得到字数,然后便利B数组,如果有字数相等的B数组元素,再进行字符串比较,处理完A的第一行后处理第二行,对第二行的字数进行判断,然后和上一次比较时POS在B数组的位置,看大于等于还是小于,如果大于或小于,直接进行前进[或]者后退遍历B数组,如果等于,记住当前位置进行前进[和]后退的处理,找到相同数字的行进行字符串内容的比较,然后继续处理A之后的行,以此类推。
    我数据结构学得也很烂,这个比较繁琐。但是和逐行比较,要快些。只是大概想法。
    上班去了哈哈。
      

  30.   

    这样子!我是这样子写的。按你的思路我应该更改哪里才能提高速度
    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;
      

  31.   

    对于这样的问题,最快的方法一定是只遍历一遍。如果不考虑内存问题,可以用trie树。
    思想:不是匹配,而是查找。
    把最小的文本建立成trie树,然后用大文本的每一行去trie树中查找,遍历到叶子即表示A与B中有相同的行。
    这种方法的查找是线性数组查找,速度非常快。每一行到另外一个文本中比较是最慢的办法,如果用hash运算的过程可能也不会太快。不过tire树是不平衡树,非常耗内存的,但速度非常快。
      

  32.   

    #2楼 得分:0回复于:2010-04-01 00:24:08如果不同行的也要KILL,那很简单的,比如要過濾掉B中的,可以把B中的分块(先读行数)存进TSTRINGLIST里(按行数存进划分,读入到TSTRINGLIST的ARRAY里),然后读一行A的,POS一下,有就KILL {如果内存够大,可以不用ARRAY} 
    与你机子的配置就有一点关系了
      

  33.   

    相同的行包含所在的位置吗?用过比较文件的软件不,用Beyond Compare么
      

  34.   

    cat A >> B|sort|uniq >newfile
    就几百M又不是什么大文件
      

  35.   

    function LoadTxtToMemory(FileName: string): TResult;
    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秒 这个应该是极限了,排不排序对这算法没影响。
      

  36.   


    ==========
    這一定是最優的方法了!能不能直接發你的project給我測試下!我的delphi2010還在下載啊!我用分塊過濾,200W從過濾25W行。得花1到3分鐘。
    我QQ:283221234,謝謝
      

  37.   


    不好意思!我的delphi7,還不支持TResult這東西, delphi下載一天了還沒完
      

  38.   

    d2007就行了
    type
      TResult = packed record
        Data: Pointer;
        Row: Cardinal;
      end;  TInputData = packed record
        Src: TResult;
        Dest: TResult;
      end;
      

  39.   

          _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);
    是创建两个线程把formlist分2块进行过滤