乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      對tmemorystream的一些改進(jìn)

       老魏的書架 2014-05-25

      怎么又是關(guān)于Stream的,呵呵,應(yīng)該說只是最近比較關(guān)心程式的效率問題,而我對Stream其實(shí)并沒有什么特別的研究,只是自己發(fā)現(xiàn)了一些新的用法,希望能對大家有用而已。

      事情的起因還是那個破爛電子相冊軟件,今天又發(fā)現(xiàn)了一個可改進(jìn)之處,有一段程式我原來是這么寫的:
      procedure CreateFile(const AFileName:String;const AStream:TMemoryStream);
      var
        FileStream:TMemoryStream;
      begin
        ShowProgressForm(nil);
        FileStream:=TMemoryStream.Create();
        try
          FileStream.LoadFromFile(AFileName);
          FileStream.Position:=FileStream.Size;
          AStream.Position:=0;
          FileStream.CopyFrom(AStream,AStream.Size);
          FileStream.SaveToFile(AFileName);
        finally
          FileStream.Free;
        end;
      end;
      為了完成將一個TMemoryStream追加到一個文件中的任務(wù),我使用了另一個TMemoryStream,讓他先打開文件,然后使用CopyFrom()函數(shù),從原始Stream中加入數(shù)據(jù),最后再保存到文件中。
      其中最糟糕的就是CopyFrom()函數(shù),他會開辟一塊新的內(nèi)存,先調(diào)用ReadBuffer()函數(shù),從源Stream中取得數(shù)據(jù),再調(diào)用自身的WriteBuffer()函數(shù),寫到自身的Buffer中,最后再釋放這塊臨時內(nèi)存,這些過程能看這段代碼:
      function TStream.CopyFrom(Source: TStream; Count: Int64): Int64;
      const
        MaxBufSize = $F000;
      var
        BufSize, N: Integer;
        Buffer: PChar;
      begin
        if Count = 0 then
        begin
          Source.Position := 0;
          Count := Source.Size;
        end;
        Result := Count;
        if Count > MaxBufSize then BufSize := MaxBufSize else BufSize := Count;
        GetMem(Buffer, BufSize);
        try
          while Count <> 0 do
          begin
            if Count > BufSize then N := BufSize else N := Count;
            Source.ReadBuffer(Buffer^, N);
            WriteBuffer(Buffer^, N);
            Dec(Count, N);
          end;
        finally
          FreeMem(Buffer, BufSize);
        end;
      end;
      而且,不知道為何,Delphi自己提供的Move()函數(shù)在內(nèi)存拷貝時顯得特別的慢。最后導(dǎo)致的結(jié)果就是,我在將30MB左右的數(shù)據(jù)寫入文件時,會花半分鐘的時間。

      知道了問題所在,那么要加速這個過程就非常簡單了,首先當(dāng)然要避免內(nèi)存拷貝,所以我決心去掉那個累贅的FileStream,讓原始Stream自己將內(nèi)存數(shù)據(jù)寫入到文件,那樣不是就能了嗎?
      不過無論是TMemoryStream,還是TFileStream,都只提供將數(shù)據(jù)完全寫入一個文件的功能,而我需要的則是追加功能,呵呵,這個簡單,自己打開文件,然后WriteFile()就能了,所以最終的解決方法就是:
      從TMemoryStream繼承出一個新類,暫且叫做TMemoryStreamEx,加入一個新的方法,叫做:AppendToFile(),能將內(nèi)存數(shù)據(jù)完全追加到已存在的文件內(nèi),函數(shù)內(nèi)容如下:
      procedure TMemoryStreamEx.AppendToFile(const AFileName:String);
      var
        FileHandle:LongWord;
        CurPos:LongWord;
        BytesWritten:LongWord;
      begin
        FileHandle:=CreateFile(PChar(AFileName),GENERIC_WRITE,0,nil,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
        if FileHandle=INVALID_HANDLE_VALUE then begin
          raise MemoryStreamExException.Create(Error when create file);
        end;
        try
          CurPos:=SetFilePointer(FileHandle,0,nil,FILE_END);
          LockFile(FileHandle,CurPos,0,Size,0);
          try
            BytesWritten:=0;
            if not WriteFile(FileHandle,Memory^,Size,BytesWritten,nil) then begin
              raise MemoryStreamExException.Create(Error when write file);
            end;
            if (Size<>BytesWritten) then begin
              raise MemoryStreamExException.Create(Wrong written size);
            end;
          finally
            UnlockFile(FileHandle,CurPos,0,Size,0);
          end;
        finally
          CloseHandle(FileHandle);
        end;
      end;

      好了,替換掉原來的那段程式,新的程式變?yōu)椋?BR>procedure TExeExporter.CreateExecutableFile(const AFileName:String;const AStream:TMemoryStreamEx);
      begin
        AStream.AppendToFile(AFileName);
      end;
      就那么簡單,速度也縮短到僅僅2-3秒了。

      最近單位做的一系列軟件也在進(jìn)行提速優(yōu)化,使用了好多方法,自己管理內(nèi)存(減少malloc的調(diào)用次數(shù)),使用HashTable存放經(jīng)常要進(jìn)行查找的數(shù)據(jù)。。。。等等,看到自己研發(fā)的軟件在速度上有了質(zhì)的飛躍,實(shí)在是非常有成就感啊。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多