S
Stephan Rose
Still been beating on my Multi Unit Scalar structure and...it's coming
along well. Since it is a core component of my app that virtually
everything builds on, even the smalles amount of performance gain is
worth it.
But I think I have hit a wall.
One million operations now average around 98ms give or take. If it's
Power 0/1 (linear unit) or Power 2+ (area, volume, etc) unit makes no
measurable difference. The additional loop makes less difference in
performance than planetary alignment. (Code is below sig for those who
wanna check it out).
So just out of boredom and because I have nothing better to do, I went
and measured the raw time the operator takes.
Namely:
public static Scalar operator + (Scalar a, Scalar b)
{
return new Scalar();
}
Result: average around 40ms!!
Wait a sec...I am spending almost half my time just in overhead for
the operator? I am betting another good portion goes to the call to
the conversion function. Making my bottom line that the operator
overhead itself is taking magnitudes more time than the actual
operation being performed.
So my question comes here: Is there anything I can do to reduce the
raw overhead of the operator itself? Compiler flag? option? attribute?
virgin sacrifice to bill gates?
Thoughts and suggestions would be very welcome!!
Thanks,
--
Stephan
2003 Yamaha R6
kimi no koto omoidasu hi
nante nai no wa
kimi no koto wasureta toki ga nai kara
public static Scalar operator + (Scalar a, Scalar b)
{
if (a.Power != b.Power) throw new
System.InvalidOperationException("Operator+pow");
switch(a.Unit)
{
case ScalarUnit.Centimeter:
return new Scalar(a.Value +
b.GetCentimeterValue(), ScalarUnit.Centimeter, a.Power);
case ScalarUnit.Inch:
return new Scalar(a.Value + b.GetInchValue(),
ScalarUnit.Inch, a.Power);
case ScalarUnit.Mil:
return new Scalar(a.Value + b.GetMilValue(),
ScalarUnit.Mil, a.Power);
case ScalarUnit.Millimeter:
return new Scalar(a.Value +
b.GetMillimeterValue(), ScalarUnit.Millimeter, a.Power);
case ScalarUnit.Degree:
return new Scalar(a.Value +
b.GetDegreeValue(), ScalarUnit.Degree, a.Power);
case ScalarUnit.Radian:
return new Scalar(a.Value +
b.GetRadianValue(), ScalarUnit.Radian, a.Power);
default:
throw new
System.InvalidOperationException("Operator+");
}
}
public double GetMillimeterValue()
{
double scale;
switch (this.Unit)
{
case ScalarUnit.Centimeter:
scale = 10.0;
break;
case ScalarUnit.Inch:
scale = 25.4;
break;
case ScalarUnit.Mil:
scale = 0.0254;
break;
case ScalarUnit.Millimeter:
return Value;
default:
throw new
System.InvalidOperationException("Cannot convert unit.");
}
if (Power > 0)
{
int p = Power - 1;
while (p-- != 0)
{
scale *= scale;
}
return Value * scale;
}
return Value * scale;
}
along well. Since it is a core component of my app that virtually
everything builds on, even the smalles amount of performance gain is
worth it.
But I think I have hit a wall.
One million operations now average around 98ms give or take. If it's
Power 0/1 (linear unit) or Power 2+ (area, volume, etc) unit makes no
measurable difference. The additional loop makes less difference in
performance than planetary alignment. (Code is below sig for those who
wanna check it out).
So just out of boredom and because I have nothing better to do, I went
and measured the raw time the operator takes.
Namely:
public static Scalar operator + (Scalar a, Scalar b)
{
return new Scalar();
}
Result: average around 40ms!!
Wait a sec...I am spending almost half my time just in overhead for
the operator? I am betting another good portion goes to the call to
the conversion function. Making my bottom line that the operator
overhead itself is taking magnitudes more time than the actual
operation being performed.
So my question comes here: Is there anything I can do to reduce the
raw overhead of the operator itself? Compiler flag? option? attribute?
virgin sacrifice to bill gates?
Thoughts and suggestions would be very welcome!!
Thanks,
--
Stephan
2003 Yamaha R6
kimi no koto omoidasu hi
nante nai no wa
kimi no koto wasureta toki ga nai kara
public static Scalar operator + (Scalar a, Scalar b)
{
if (a.Power != b.Power) throw new
System.InvalidOperationException("Operator+pow");
switch(a.Unit)
{
case ScalarUnit.Centimeter:
return new Scalar(a.Value +
b.GetCentimeterValue(), ScalarUnit.Centimeter, a.Power);
case ScalarUnit.Inch:
return new Scalar(a.Value + b.GetInchValue(),
ScalarUnit.Inch, a.Power);
case ScalarUnit.Mil:
return new Scalar(a.Value + b.GetMilValue(),
ScalarUnit.Mil, a.Power);
case ScalarUnit.Millimeter:
return new Scalar(a.Value +
b.GetMillimeterValue(), ScalarUnit.Millimeter, a.Power);
case ScalarUnit.Degree:
return new Scalar(a.Value +
b.GetDegreeValue(), ScalarUnit.Degree, a.Power);
case ScalarUnit.Radian:
return new Scalar(a.Value +
b.GetRadianValue(), ScalarUnit.Radian, a.Power);
default:
throw new
System.InvalidOperationException("Operator+");
}
}
public double GetMillimeterValue()
{
double scale;
switch (this.Unit)
{
case ScalarUnit.Centimeter:
scale = 10.0;
break;
case ScalarUnit.Inch:
scale = 25.4;
break;
case ScalarUnit.Mil:
scale = 0.0254;
break;
case ScalarUnit.Millimeter:
return Value;
default:
throw new
System.InvalidOperationException("Cannot convert unit.");
}
if (Power > 0)
{
int p = Power - 1;
while (p-- != 0)
{
scale *= scale;
}
return Value * scale;
}
return Value * scale;
}