View Issue Details

IDProjectCategoryView StatusLast Update
0035389LazarusTAChartpublic2019-04-17 04:03
ReporterMarcin WiazowskiAssigned Towp 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version2.1 (SVN)Product Build60989 
Target Version2.2Fixed in Version 
Summary0035389: TAChart: faster extent calculation thanks to sorting
DescriptionI'm attaching a patch to make calculation of basic extent faster, if data source is sorted. I think, that the code is rather self-explaining.
TagsNo tags attached.
Fixed in Revision60991, 60998
LazTarget2.2
WidgetsetWin32/Win64
Attached Files
  • patch.diff (2,454 bytes)
    Index: components/tachart/tacustomsource.pas
    ===================================================================
    --- components/tachart/tacustomsource.pas	(revision 60988)
    +++ components/tachart/tacustomsource.pas	(working copy)
    @@ -811,28 +811,38 @@
         exit(FBasicExtent);
       FBasicExtent := EmptyExtent;
     
    -  if XCount > 0 then begin
    -    if HasXErrorBars then
    -      for i := 0 to Count - 1 do begin
    -        GetXErrorBarLimits(i, vhi, vlo);
    -        UpdateMinMax(vhi, FBasicExtent.a.X, FBasicExtent.b.X);
    -        UpdateMinMax(vlo, FBasicExtent.a.X, FBasicExtent.b.X);
    -      end
    -    else
    -      for i:=0 to Count - 1 do
    -        UpdateMinMax(Item[i]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
    -  end;
    +  if Count > 0 then begin
    +    if XCount > 0 then begin
    +      if HasXErrorBars then
    +        for i := 0 to Count - 1 do begin
    +          GetXErrorBarLimits(i, vhi, vlo);
    +          UpdateMinMax(vhi, FBasicExtent.a.X, FBasicExtent.b.X);
    +          UpdateMinMax(vlo, FBasicExtent.a.X, FBasicExtent.b.X);
    +        end
    +      else
    +      if (FSortBy = sbX) and (FSortIndex = 0) then begin
    +        UpdateMinMax(Item[0]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
    +        UpdateMinMax(Item[Count-1]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
    +      end else
    +        for i:=0 to Count - 1 do
    +          UpdateMinMax(Item[i]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
    +    end;
     
    -  if YCount > 0 then begin
    -    if HasYErrorBars then
    -      for i := 0 to Count - 1 do begin
    -        GetYErrorBarLimits(i, vhi, vlo);
    -        UpdateMinMax(vhi, FBasicExtent.a.Y, FBasicExtent.b.Y);
    -        UpdateMinMax(vlo, FBasicExtent.a.Y, FBasicExtent.b.Y);
    -      end
    -    else
    -      for i:=0 to Count - 1 do
    -        UpdateMinMax(Item[i]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
    +    if YCount > 0 then begin
    +      if HasYErrorBars then
    +        for i := 0 to Count - 1 do begin
    +          GetYErrorBarLimits(i, vhi, vlo);
    +          UpdateMinMax(vhi, FBasicExtent.a.Y, FBasicExtent.b.Y);
    +          UpdateMinMax(vlo, FBasicExtent.a.Y, FBasicExtent.b.Y);
    +        end
    +      else
    +      if (FSortBy = sbY) and (FSortIndex = 0) then begin
    +        UpdateMinMax(Item[0]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
    +        UpdateMinMax(Item[Count-1]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
    +      end else
    +        for i:=0 to Count - 1 do
    +          UpdateMinMax(Item[i]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
    +    end;
       end;
     
       FBasicExtentIsValid := true;
    
    patch.diff (2,454 bytes)

Activities

Marcin Wiazowski

2019-04-16 02:40

reporter  

patch.diff (2,454 bytes)
Index: components/tachart/tacustomsource.pas
===================================================================
--- components/tachart/tacustomsource.pas	(revision 60988)
+++ components/tachart/tacustomsource.pas	(working copy)
@@ -811,28 +811,38 @@
     exit(FBasicExtent);
   FBasicExtent := EmptyExtent;
 
-  if XCount > 0 then begin
-    if HasXErrorBars then
-      for i := 0 to Count - 1 do begin
-        GetXErrorBarLimits(i, vhi, vlo);
-        UpdateMinMax(vhi, FBasicExtent.a.X, FBasicExtent.b.X);
-        UpdateMinMax(vlo, FBasicExtent.a.X, FBasicExtent.b.X);
-      end
-    else
-      for i:=0 to Count - 1 do
-        UpdateMinMax(Item[i]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
-  end;
+  if Count > 0 then begin
+    if XCount > 0 then begin
+      if HasXErrorBars then
+        for i := 0 to Count - 1 do begin
+          GetXErrorBarLimits(i, vhi, vlo);
+          UpdateMinMax(vhi, FBasicExtent.a.X, FBasicExtent.b.X);
+          UpdateMinMax(vlo, FBasicExtent.a.X, FBasicExtent.b.X);
+        end
+      else
+      if (FSortBy = sbX) and (FSortIndex = 0) then begin
+        UpdateMinMax(Item[0]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
+        UpdateMinMax(Item[Count-1]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
+      end else
+        for i:=0 to Count - 1 do
+          UpdateMinMax(Item[i]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
+    end;
 
-  if YCount > 0 then begin
-    if HasYErrorBars then
-      for i := 0 to Count - 1 do begin
-        GetYErrorBarLimits(i, vhi, vlo);
-        UpdateMinMax(vhi, FBasicExtent.a.Y, FBasicExtent.b.Y);
-        UpdateMinMax(vlo, FBasicExtent.a.Y, FBasicExtent.b.Y);
-      end
-    else
-      for i:=0 to Count - 1 do
-        UpdateMinMax(Item[i]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
+    if YCount > 0 then begin
+      if HasYErrorBars then
+        for i := 0 to Count - 1 do begin
+          GetYErrorBarLimits(i, vhi, vlo);
+          UpdateMinMax(vhi, FBasicExtent.a.Y, FBasicExtent.b.Y);
+          UpdateMinMax(vlo, FBasicExtent.a.Y, FBasicExtent.b.Y);
+        end
+      else
+      if (FSortBy = sbY) and (FSortIndex = 0) then begin
+        UpdateMinMax(Item[0]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
+        UpdateMinMax(Item[Count-1]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
+      end else
+        for i:=0 to Count - 1 do
+          UpdateMinMax(Item[i]^.Y, FBasicExtent.a.Y, FBasicExtent.b.Y);
+    end;
   end;
 
   FBasicExtentIsValid := true;
patch.diff (2,454 bytes)

wp

2019-04-16 09:37

developer   ~0115539

Applied, thanks.

Marcin Wiazowski

2019-04-16 18:04

reporter   ~0115557

Semi-related: I can see a new code in TCustomChartSource.BasicExtent():

  end else begin
    UpdateMinMax(0, FBasicExtent.a.X, FBasicExtent.b.X);
    UpdateMinMax(Count-1, FBasicExtent.a.X, FBasicExtent.b.X);
  end;

In this specific case, this can be made even simpler:

  end else begin
    FBasicExtent.a.X := 0;
    FBasicExtent.b.X := Count-1;
  end;

wp

2019-04-16 19:58

developer   ~0115563

Of course.

Marcin Wiazowski

2019-04-17 04:03

reporter   ~0115575

Confirmed, thanks.

Issue History

Date Modified Username Field Change
2019-04-16 02:40 Marcin Wiazowski New Issue
2019-04-16 02:40 Marcin Wiazowski File Added: patch.diff
2019-04-16 09:37 wp Fixed in Revision => 60991
2019-04-16 09:37 wp LazTarget => 2.2
2019-04-16 09:37 wp Note Added: 0115539
2019-04-16 09:37 wp Status new => resolved
2019-04-16 09:37 wp Resolution open => fixed
2019-04-16 09:37 wp Assigned To => wp
2019-04-16 09:37 wp Target Version => 2.2
2019-04-16 18:04 Marcin Wiazowski Note Added: 0115557
2019-04-16 18:04 Marcin Wiazowski Status resolved => assigned
2019-04-16 18:04 Marcin Wiazowski Resolution fixed => reopened
2019-04-16 19:58 wp Note Added: 0115563
2019-04-16 19:58 wp Fixed in Revision 60991 => 60991, 60998
2019-04-16 19:58 wp Status assigned => resolved
2019-04-16 19:58 wp Resolution reopened => fixed
2019-04-17 04:03 Marcin Wiazowski Note Added: 0115575
2019-04-17 04:03 Marcin Wiazowski Status resolved => closed