Invece di leggere e scrivere un carattere alla volta, leggere e scrivere tutti in una volta:
procedure WriteWideString(const ws: WideString; stream: TStream);
var
nChars: LongInt;
begin
nChars := Length(ws);
stream.WriteBuffer(nChars, SizeOf(nChars);
if nChars > 0 then
stream.WriteBuffer(ws[1], nChars * SizeOf(ws[1]));
end;
function ReadWideString(stream: TStream): WideString;
var
nChars: LongInt;
begin
stream.ReadBuffer(nChars, SizeOf(nChars));
SetLength(Result, nChars);
if nChars > 0 then
stream.ReadBuffer(Result[1], nChars * SizeOf(Result[1]));
end;
Ora, tecnicamente, dal momento che WideString
è un Windows BSTR
, si può contenere un numero di byte pari a dispari. La funzione Length
legge il numero di byte e divide per due, quindi è possibile (anche se non è probabile) che il codice sopra taglierà l'ultimo byte. Si potrebbe utilizzare questo codice invece:
procedure WriteWideString(const ws: WideString; stream: TStream);
var
nBytes: LongInt;
begin
nBytes := SysStringByteLen(Pointer(ws));
stream.WriteBuffer(nBytes, SizeOf(nBytes));
if nBytes > 0 then
stream.WriteBuffer(Pointer(ws)^, nBytes);
end;
function ReadWideString(stream: TStream): WideString;
var
nBytes: LongInt;
buffer: PAnsiChar;
begin
stream.ReadBuffer(nBytes, SizeOf(nBytes));
if nBytes > 0 then begin
GetMem(buffer, nBytes);
try
stream.ReadBuffer(buffer^, nBytes);
Result := SysAllocStringByteLen(buffer, nBytes)
finally
FreeMem(buffer);
end;
end else
Result := '';
end;
Ispirato Mghie's answer, hanno sostituito i miei Read
e Write
chiamate con ReadBuffer
e WriteBuffer
. Quest'ultimo genererà eccezioni se non sono in grado di leggere o scrivere il numero richiesto di byte.
fonte
2009-08-30 15:38:10
Modifica di un'area particolare del codice perché si * crede Eve * potrebbe essere il collo di bottiglia può essere un enorme spreco di tempo. Dovresti misurare prima, ci sono molti strumenti per aiutarti, alcuni gratuiti, altri commerciali. Prova questi primi per alcuni link: http://stackoverflow.com/questions/291631/profiler-and-memory-analysis-tools-for-delphi e http://stackoverflow.com/questions/368938/delphi-profiling-tools – mghie
Grazie, ma stavo usando QueryPerformanceCounter per rilevarlo;) comunque quello era sicuramente il collo di bottiglia, dato che leggere char in char è molto lento ... tutte le altre operazioni stavano solo salvando alcuni dati binari brevi. – migajek
Ah, OK.Stavo solo reagendo al tuo uso delle parole "credo" e "potrebbe", mi dispiace quindi per la predica ;-) – mghie