How could one boost sdcard access lazarus / 43-Android ---------------------------------------------------------------------- stab · 2013-01-03 15:11 Hi all, I'm trying to make an android app for fleetmanagement with a map-background where you should be able to zoom and pan. Map-data is organised as blocks in a file with some meta-data as a header containing information about projection, extent in world-coordinates and resolution. The header is followed by a table containing pointers to and sizes of the blocks. After that follows all the blocks that are single png-files. Access to map-data is done through three methods of an custom object shown below. function TKIRObject.GetPNGImageWithInRectangle(x1, y1, x2, y2: double) : boolean; begin // code to calculate input-worldcoordinates to start- and enblocks   GetMapWithInRectangle(StartBlockNr, EndBlockNr); end; function TKIRObject.GetMapWithInRectangle(StartBlockNr, EndBlockNr: LongWord) : boolean; var   col, row, blocknr, x, y : LongWord;   AWidth, AHeight : integer;   StartCol, StartRow, EndCol, EndRow, temp : LongWord;   westStartBlockNr : integer;   tstart1, tstart2, tstart3, tstart4, tstart5, tstart6 : tdatetime;   tend1, tend2, tend3, tend4, tend5, tend6 : tdatetime;   tmax1, tmax2, tmax3, tmax4, tmax5, tmax6 : tdatetime; begin   Result := true;   tMax1 := 0;   tMax2 := 0;   tMax3 := 0;   totBlocks := 0;   tStart1 := Now;     FPng.Clear; // calculate startcolumn, endcolumg, startrow and endrow of resulting pngImage built by current blocks   BlockNrToColRow(StartBlockNr, StartCol, StartRow);   BlockNrToColRow(EndBlockNr, EndCol, EndRow);   westStartBlockNr := StartBlockNr;   if StartCol > EndCol then   begin     temp := EndCol;     EndCol := StartCol;     StartCol := temp;   end;   if StartRow > EndRow then   begin     temp := EndRow;     EndRow := StartRow;     StartRow := temp;   end; // determine size of resulting pngImage   AWidth := FInfo.BlockSizeEast * (EndCol - StartCol + 1);   AHeight := FInfo.BlockSizeNorth * (EndRow - StartRow + 1);   FPng.SetSize(AWidth, AHeight);   try     row := StartRow;     while row < EndRow + 1 do     begin       col := StartCol;       while col < EndCol + 1 do       begin  // determine block by current column and row        blockNr := ColRowToBlockNr(col, row);         if blockNr > westStartBlockNr + FNumBlocksEast - 1 then           Break;         tStart2 := Now; // read block         ReadPNGBlock(blocknr, FBlockPng);         tEnd2 := Now;         Inc(totBlocks);         if FBlockPng.Width = 0 then         begin           inc(col);           Continue;         end; //        FBlockPng.SaveToFile(ExtractFilePath(Application.Exename) + 'Read' + IntToStr(blocknr) + '.png');         x := (col - StartCol) * FInfo.BlockSizeEast;         y := (row - StartRow) * FInfo.BlockSizeNorth;         tStart3 := Now; // copy block to resulting pngImage         FPng.Canvas.CopyRect(Rect(x, y, x + png.Width, y + png.Height),           FBlockPng.Canvas, Rect(0, 0, png.Width, png.Height)); //        FPng.SaveToFile(ExtractFilePath(Application.Exename) + 'Tot' + IntToStr(blocknr) + '.png');         tEnd3 := Now;         Inc(col);       end;       westStartBlockNr := westStartBlockNr + Finfo.BlockCountEast;       Inc(row);     end;     tEnd1 := Now;     tMax1 := tEnd1 - tStart1; // Total time for totBlocks     tMax2 := tEnd2 - tStart2; // time to read one block ReadPNGBlock     tMax3 := tEnd3 - tStart3; // time for FPng.Canvas.CopyRect   except     Result := false;   end; end; procedure TKIRObject.ReadPNGBlock(BlockNum: integer; var png : TPortableNetworkGraphic); var   loffset1 : LongWord;   memStream : TMemoryStream; begin   png.Clear;   if FBlockOffsetPointerArray = nil then Exit; //We use the offset array to find the offset of the requested mapblock   loffset1 := FBlockOffsetPointerArray[BlockNum].Position;   FFileStream.Position := loffset1;   FBlockSize := FBlockOffsetPointerArray[BlockNum].BlockSize;   if FBlockSize = 0 then Exit;   memStream := TMemoryStream.Create;   try     memStream.CopyFrom(FFileStream, FBlockSize);     l := memStream.Size;     if memStream.Size > 0 then     begin       memStream.Position := 0;       png.LoadFromStream(memStream);     end;   finally     FreeandNil(memStream);   end; end; In method: GetMapWithInRectangle(StartBlockNr, EndBlockNr) I made benchmark on PC and a smartphone when retrieving a map containing 12 blocks. Benchmark-result below: ______________________________________________________________________ __________ Device         ReadPNGBlock   FPng.Canvas.CopyRect    NumBlocks      TotalTime ______________________________________________________________________ __________ PC: Win 7/64bits           4 ms                 3 ms                           12                 84 ms 8 Gb Ram 2.7 GHz ______________________________________________________________________ __________ Sony-Ericsson XPeria, X10i Android 2.3.3         36 ms              63 ms                            12             1258 ms    384 Mb Ram CPU 1 GHz GPU Adreno 200 ______________________________________________________________________ __________ Access to 12 blocks on the smartphone is almoust 15 times slower than on PC. I also made a test reading png:s(120kb 480x780 pixels) from disk with LoadFrom File on PC and smartphone and got these access-times: PC: 47 ms   smartphone: 490ms In this case the factor is 10 With this access-time in android, the app is almost useless. Can someone either point at some mistake I'm doing or suggest something to boost speed in android? Regards stab ---------------------------------------------------------------------- Leledumbo · 2013-01-03 16:07 Buy a new SD card with higher classIncrease OS I/O read buffer ---------------------------------------------------------------------- stab · 2013-01-03 16:31 Thanks for answering, Does your answer mean that you don't find any big mistake in my code? /stab ---------------------------------------------------------------------- stab · 2013-01-03 16:42 How do I increase OS I/O read buffer? From my benchmark all is OK on PC but in smartphone it might be useful. /stab ---------------------------------------------------------------------- marcov · 2013-01-03 23:02 Is it sure it is the I/O and not the decompression in PNG?