用汇编能快多少?我走投无路了。
            for j := 0 to 499 do
            begin
                currrecord:=recbuf[j];
                pos := $30 + currrecord[$34] + $58;
                len := (currrecord[pos]) shl 1;
                if (len=0)or(len>50) then continue;
                pos := pos + 2;
                copymemory(@padding[0], @currrecord[pos], len);
                padding[len]:=0;
                padding[len+1]:=0;
                copymemory(p, @padding[0], len+2);
                listbox1.items.add(p);
                inc(count);
                label2.caption := inttostr(count);
                application.ProcessMessages;
            end;
currrecord是1024字节的数组。以上代码在外面再套一个循环时耗时太多了,不能接受
这段代码的功能是在currrecord的某个位置取一unicode,显示在listbox中

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject);
    const
        currrecord: array[0..$100-1] of byte = (
            $46, $49, $4C, $45, $2A, $00, $03, $00, $C6, $68, $6B, $0F, $00, $00, $00, $00,
            $01, $00, $01, $00, $30, $00, $01, $00, $90, $01, $00, $00, $00, $04, $00, $00,
            $00, $00, $00, $00, $00, $00, $00, $00, $06, $00, $76, $03, $00, $00, $00, $00,
            $10, $00, $00, $00, $60, $00, $00, $00, $00, $00, $18, $00, $00, $00, $00, $00,
            $48, $00, $00, $00, $18, $00, $00, $00, $A0, $F9, $EB, $5C, $E8, $66, $C2, $01,
            $A0, $F9, $EB, $5C, $E8, $66, $C2, $01, $A0, $F9, $EB, $5C, $E8, $66, $C2, $01,
            $A0, $F9, $EB, $5C, $E8, $66, $C2, $01, $06, $00, $00, $00, $00, $00, $00, $00,
            $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $01, $00, $00,
            $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
            $30, $00, $00, $00, $68, $00, $00, $00, $00, $00, $18, $00, $00, $00, $03, $00,
            $4A, $00, $00, $00, $18, $00, $01, $00, $05, $00, $00, $00, $00, $00, $05, $00,
            $A0, $F9, $EB, $5C, $E8, $66, $C2, $01, $A0, $F9, $EB, $5C, $E8, $66, $C2, $01,
            $A0, $F9, $EB, $5C, $E8, $66, $C2, $01, $A0, $F9, $EB, $5C, $E8, $66, $C2, $01,
            $00, $40, $00, $00, $00, $00, $00, $00, $00, $40, $00, $00, $00, $00, $00, $00,
            $06, $00, $00, $00, $00, $00, $00, $00, $04, $03, $24, $00, $4D, $00, $46, $00,
            $54, $00, $00, $00, $00, $00, $00, $00, $80, $00, $00, $00, $48, $00, $00, $00);var
        tmp: array of char;
        p: pwidechar;
        i, j: integer;
        count: integer;
        jk: integer;
        pos: integer;
        len: integer;
        padding: array[0..100] of byte;
    begin
        count := 0;
        jk := gettickcount;
        listbox1.clear;
        getmem(p, 100);
        lockwindowupdate(listbox1.handle);
        for i := 1 to 30 do
        begin
            label1.caption := inttostr(i);
            for j := 0 to 499 do
            begin
                pos := $30 + currrecord[$34] + $58;
                len := (currrecord[pos]) shl 1;
                if (len = 0) or (len > 50) then continue;
                pos := pos + 2;
                copymemory(@padding[0], @currrecord[pos], len);
                padding[len] := 0;
                padding[len + 1] := 0;
                copymemory(p, @padding[0], len + 2);
                listbox1.items.add(p);
                inc(count);
                label2.caption := inttostr(count);
                application.ProcessMessages;
            end;
        end;
        showmessage(inttostr(gettickcount - jk));
        lockwindowupdate(0);
        freemem(p);
    end;汇编都忘了,回家翻书去
      

  2.   

    我将Label1, Label2的显示代码去了,程序执行用了0.186秒左右,
    再将LockWindowUpdate改成ListBox1.BeginUpdate/EndUpdate,时间也少了点。
    还有
              for J := 0 to 499 do
              begin
                pos := $30 + currrecord[$34] + $58;
                len := (currrecord[pos]) shl 1;
                if (len = 0) or (len > 50) then continue;
                pos := pos + 2;
                //你是不是写错了,pos,Len返回的不是一样的,每次??
      

  3.   

    to  copy_paste(木石三);
      谢谢;
      这是一段演示代码,currrecord的值只有一个所以,pos和len每次都一样,实际程序中当然不会一样。我用这段代码来列ntfs分区的文件,现在每秒能列1000个,不够快,起码要再快一倍才行的。我列自已的有170000个文件的分区要用3分钟,受不了。
      

  4.   

    我只能写到这份上:
    var
      P: PWideChar;
      Start: Cardinal;
      I, J, Pos, Len: Integer;
      padding: array[0..100] of byte;
    begin
      Start := GetTickCount;
      GetMem(P, 100);
      Listbox1.Items.BeginUpdate;
      try
        ListBox1.Items.Clear;
        for i := 1 to 30 do
          for j := 0 to 499 do
          begin
            pos := $30 + currrecord[$34] + $58;
            len := (currrecord[pos]) shl 1;
            if (len = 0) or (len > 50) then
              continue;
            pos := pos + 2;
            Move(CurrRecord[Pos], Padding, Len);
            padding[len] := 0;
            padding[len + 1] := 0;
            Move(Padding, P^, Len + 2);
            listbox1.items.add(p);
          end;
      finally
        Freemem(P);
        ListBox1.Items.EndUpdate;
      end;
      Caption := FloatToStr((GetTickCount - Start) / 1000);
    end;按你情况,可用线程,还有你所说有那么多文件,有必要一次性全列出来吗?
    我以前在读注册表时,也只是每读两层,全部加载则
      

  5.   

    谢谢木石三,我的情况是大量时间花在运算上,I/O用时并不多,我想用线程不是很有意义。你说的第二点倒真是在点子上,可不把所有文件列出来目录树就可能不完整,可能是我对ntfs结构了解还不全吧。下班前结贴,如果没有好的结果分全给你。
      

  6.   

    试试这个,用流方式来加载,我这里不行,感觉比上面快:
    var
      //P: PWideChar;
      Stream: TMemoryStream;
      Start: Cardinal;
      I, J, Pos, Len: Integer;
      padding: array[0..100] of byte;
    begin
      Start := GetTickCount;
      //GetMem(P, 100);
      Stream := TmemoryStream.Create;
      Listbox1.Items.BeginUpdate;
      try
        ListBox1.Items.Clear;
        for i := 1 to 30 do
          for j := 0 to 499 do
          begin
            pos := $30 + currrecord[$34] + $58;
            len := (currrecord[pos]) shl 1;
            if (len = 0) or (len > 50) then
              continue;
            pos := pos + 2;
            Move(CurrRecord[Pos], Padding, Len);
            padding[len] := 0;
            padding[len + 1] := 0;
            //Move(Padding, P^, Len + 2);
            Stream.WriteBuffer(Padding[0], Len + 2);
          end;
        ListBox1.Items.Text := PWideChar(Stream.Memory);
      finally
        //FreeMem(P);
        Stream.Free;
        ListBox1.Items.EndUpdate;
      end;
      Caption := FloatToStr((GetTickCount - Start) / 1000);
    end;
      

  7.   

    to mengxianbao1521(这样也可以!) :
      过谦了,就代码本身来说这段没什么的,就是我的要求可能离谱了点。