Steema Issues Database

Note: This database is for bugs and wishes only. For technical support help, if you are a customer please visit our online forums;
otherwise you can use StackOverflow.
Before using this bug-tracker we recommend a look at this document, Steema Bug Fixing Policy.



Bug 2539 - ColorRange is inefficient
Summary: ColorRange is inefficient
Status: CONFIRMED
Alias: None
Product: .NET TeeChart
Classification: Unclassified
Component: Series (show other bugs)
Version: unspecified
Hardware: PC Windows
: --- major
Target Milestone: ---
Assignee: Steema Issue Manager
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-07-24 08:17 EDT by Fraser Ross
Modified: 2022-09-23 08:12 EDT (History)
2 users (show)

See Also:
Chart Series: ---
Delphi / C++ Builder RAD IDE Version:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fraser Ross 2022-07-24 08:17:05 EDT
I have known about this problem for many years.  I did think it had been reported.  I remember being shown the functions implementation somehow.  Here it is taken from a forum post in 2010:

        private void ColorRange(Steema.TeeChart.Styles.Series ASeries, Steema.TeeChart.Styles.ValueList AValueList, double FromValue, double ToValue, Color AColor)
        {
            double tmpValue;
            for (int t = 0; t < AValueList.Count; t++)
            {
                tmpValue = AValueList.Value[t];
                if ((tmpValue >= FromValue) && (tmpValue <= ToValue) && (!ASeries.IsNull(t)))
                    ASeries.Colors[t] = AColor;
            }
            tChart1.Refresh();
        }

My alternative to using is like this:

	auto const xEnd= range.End();
	for (auto x= range.Start(); xEnd != x; ++x)
		pulseLengthsSeries->ValueColor[x]= TColor(colour);

The constant xEnd is thought to significantly optimise speed.
Comment 1 yeray alonso 2022-09-23 07:08:21 EDT
Sounds as the code posted here:

https://www.steema.com/support/viewtopic.php?f=4&t=10655&p=44710&hilit=ColorRange#p44710

I'm moving this to TeeChart .NET
Comment 2 christopher ireland 2022-09-23 08:12:06 EDT
It's an interesting issue. I've created three classes which we can copy/paste into https://sharplab.io and decompile to CIL:

1. the code as-is:
*************
using System.Collections.Generic;
using System.Drawing;

public class C
{
  List<Color> Colors = new List<Color>();

  public void ColorRange(List<double> AValueList, double FromValue, double ToValue, Color AColor)
  {
    double tmpValue;
    for (var t = 0; t < AValueList.Count; t++)
    {
      tmpValue = AValueList[t];
      if ((tmpValue >= FromValue) && (tmpValue <= ToValue))
      {
        Colors[t] = AColor;
      }
    }
  }
}
*************

2. the code in which we don't query Count on every iteration:
*************
using System.Collections.Generic;
using System.Drawing;

public class D
{
  List<Color> Colors = new List<Color>();

  public void ColorRange(List<double> AValueList, double FromValue, double ToValue, Color AColor)
  {
    double tmpValue;
    int xEnd = AValueList.Count;
    for (var t = 0; t < xEnd; t++)
    {
      tmpValue = AValueList[t];
      if ((tmpValue >= FromValue) && (tmpValue <= ToValue))
      {
        Colors[t] = AColor;
      }
    }
  }
}
*************

3. And a LINQ one-liner:
*************
using System.Collections.Generic;
using System.Drawing;
using System.Linq;


public class E
{
  List<Color> Colors = new List<Color>();

  public void ColorRange(List<double> AValueList, double FromValue, double ToValue, Color AColor)
  {
    Colors = AValueList.Select((x, i) => (x <= ToValue && x <= FromValue) ? AColor : Colors[i]).ToList();
  }
}
*************

If we compare the three CIL ouputs in a diff tool, we can see that:
a) version 3) has the shortest CIL for the method, but the longest CIL for the class
b) version 1) has the shortest CIL for the class
c) both version 1) and version 2) have three callvirt calls, but 1) has all three in the loop
d) version 3) has only one callvirt call