Page 1 of 1
[patch_done] Very slowly post data (BLOB)
Posted: 22.06.2010, 07:37
by _TwoZZ_
Hi,
I'm having trouble on D2010 + ZEOSLIB_TESTING_REV800 + SQLITE-3.6.23.1.:
Very slowly post data in BLOB field (I write down images - 2 minutes write 1000Kb
![Crying or Very Sad :cry:](./images/smilies/icon_cry.gif)
):
Code: Select all
zq.SQL.Text := 'UPDATE pages SET name='''+LabeledEdit1.Text+''',';
ZQuery1.SQL.Add(pic = :pic ');
ZQuery1.SQL.Add(' WHERE id = ''' + PageID'''');
Stream := TFileStream.Create(FileName,fmOpenRead);
ZQuery1.ParamByName('model').LoadFromStream(Stream, ftGraphic);
ZQuery1.ExecSQL;
Stream.free;
Has found out, that the reason of it is encoding of data ("ZDbcSqLiteUtils.pas"):
Code: Select all
function NewEncodeString(Value: ansistring): ansistring;
var
I: Integer;
SrcLength, DestLength: Integer;
SrcBuffer, DestBuffer: PAnsiChar;
IH : integer;
begin
SrcLength := Length(Value);
SrcBuffer := PAnsiChar(Value);
DestLength := 2+ 2*SrcLength; // Hex-value double
SrcBuffer := PAnsiChar(Value);
result := '';
for I := 1 to SrcLength do
begin
IH := ord(SrcBuffer^);
result := result + IntToHex(IH,2);
Inc(SrcBuffer,1);
end;
result := 'x'+QuotedStr(result);
end;
There is a decision of the given problem?
Thx.
Evgeny.
Posted: 29.08.2010, 21:10
by mdaems
Hi,
Do you know a better way to encode a string into a hexadecimal representation ofd the BLOB?
You could try to replace the addition of small strings at the end of 'result' by more efficient string operations on a temporary string instead of using the special 'result' variable.
Maybe you should contact 'fst001' on this forum, as it was he who did sent the patch that changed ths behaviour.
Mark
Posted: 30.08.2010, 08:52
by klchin
Hi,
I think the slow was due to
result := result + IntToHex(IH,2); <-- slow process
Why not try to convert to a small string and do a mem copy ie.
SetLength( Result,Length(SrcData) * 2 );
nchr := 1;
...
tmp := IntToHex(IH,2);
Result[nchr] := tmp[1];
Result[nchr + 1] := tmp[2];
nchr := nchr + 2;
...
Regards,
KL Chin
Posted: 01.09.2010, 23:17
by mdaems
klchin,
Would you care to write real code I can commit to the SVN repository?
Posted: 02.09.2010, 03:24
by klchin
Hi Mark,
Here the code, I had not tested. Pls. veify it.
function NewEncodeString( Value : ansistring ) : ansistring;
var
I : Integer;
SrcLength : Integer; // ,DestLength
SrcBuffer : PAnsiChar; // , DestBuffer
ihx : integer; // IH,
shx : ansistring;
begin
SrcLength := Length(Value);
// SrcBuffer := PAnsiChar(Value);
// DestLength := 2+ 2*SrcLength; // Hex-value double
SrcBuffer := PAnsiChar(Value);
// result := '';
SetLength( Result,1 + SrcLength * 2 );
Result[1] := 'x';
ihx := 2;
for I := 1 to SrcLength do
begin
// IH := ord(SrcBuffer^);
// result := result + IntToHex(IH,2);
shx := IntToHex( ord(SrcBuffer^),2 );
result[ihx] := shx[1]; Inc( ihx,1 );
result[ihx] := shx[2]; Inc( ihx,1 );
Inc(SrcBuffer,1);
end;
// result := 'x'+QuotedStr(result); // since result is Hex string
end;
Regards,
KL Chin
Posted: 02.09.2010, 06:42
by mdaems
klchin,
At first look I'm missing the quotes in the resultstring. Also 'Inc(SrcBuffer,1) seems dangerous, certainly with the new compilers.
Didn't try compiling yet. Going to work now.
Mark
Posted: 03.09.2010, 10:40
by guidoaerts
would this work?
for I := 0 to SrcLength -1 do
begin
shx := IntToHex( ord(SrcBuffer),2 );
result[1+i*2] := shx[1];
result[1+i*2] := shx[2];
end;
// result := 'x'+QuotedStr(result); // since result is Hex string
end;
Posted: 04.09.2010, 05:15
by klchin
Hi Mark,
Unless the PAsniChar was not "1 BYTE", otherwise should be ok, i think.
or use SrcBuffer : PChar or PByte instead;
Hi guidoaerts,
because i started from 0
result[1] := 'x';
result[2+i*2] := shx[1];
result[3+i*2] := shx[2];
Btw, not using I*2 for performance, unless compiler full optimized for speed.
maybe code below will be faster
pdst : PChar;
pdst := @Result[2];
pdst^ := shx[1]; Inc( pdst,1 );
pdst^ := shx[2]; Inc( pdst,1 );
Posted: 04.09.2010, 21:38
by mdaems
Please, did anyone of you test his correction?
It seems to me this code can't work as long as this line is commented???
Code: Select all
// result := 'x'+QuotedStr(result); // since result is Hex string
Mark
Posted: 06.09.2010, 03:55
by klchin
Hi Mark,
I think I make a mistake, the code should be
result[ihx] := shx[2]; Inc( ihx,1 ); // Hi Byte
result[ihx] := shx[1]; Inc( ihx,1 ); // Lo Byte
BTW, what is QuotedStr do? Convert ABC to 'ABC' or none?
Regards,
KL Chin
Posted: 08.09.2010, 21:38
by mdaems
See
http://delphi.about.com/library/rtl/blrtlQuotedStr.htm
As you are converting the BLOB into the hexadecimal representation, it's probably best when you just add the quotes without using QuotedStr.
I think the final string should be x'A26C....'
Mark
Posted: 09.09.2010, 04:38
by klchin
Then the code will be
SetLength( Result,3 + SrcLength * 2 );
Result[1] := 'x'; // set x
Result[2] := ''''; // set Open Quote
ihx := 3; // set 1st hex location
for I := 1 to SrcLength do
begin
shx := IntToHex( ord(SrcBuffer^),2 ); // '3E'
result[ihx] := shx[1]; Inc( ihx,1 ); // copy '3'
result[ihx] := shx[2]; Inc( ihx,1 ); // copy 'E'
Inc( SrcBuffer,1 ); // next byte source location
end;
result[ihx] := ''''; // set Close Quote
KL Chin
Posted: 19.09.2010, 21:04
by mdaems
Thanks klchin,
I did test and commit the change a few days ago.
SVN Rev. 813.
A very quick speed test showed your code was about 3 times faster than the original version in the case I tested on Lazarus.
Mark