UPDATE
The main questions remain the ones
under the example, but I guess it boils down
to :
**If you have a type where 99% of the values could be represented in one
fast, powerfull type, and only 1% in a
very heavy type, (say int vs.
BigInteger) How to represent it?? **
A school we learned a lot about internal representations, but never how to change it at runtime. I mean : suppose you have a class representing a decimal, but you use an integer to represent it internal, until you actually need a bigger value than the integer, and only than change representation...
I never thought of this before, and when thinkihng of it, I thought that would never work, since all the checks would kill it. But I just did a test since I'm too curious for my own good and there do exist situations when changing of representation is more perormant : given this interface :
interface INumber
{
void add1000();
void SetValue(decimal d);
decimal GetValue();
}
I found the latter of the two implementations to be more powerful in a lot of situations, including this one that I composed to attract as many ideas I could on the matter (not rep, it's community)
1. Representation by only a decimal
public class Number1:INumber
{
private decimal d { get; set; }
public void add1000()
{
d += 1000;
}
public decimal GetValue()
{
return d;
}
public void SetValue(decimal d)
{
this.d = d;
}
}
2. Representation by a decimal and an int
public class Number2:INumber
{
private bool usedecimal;
private int i;
private decimal d;
public void add1000()
{
if (usedecimal)
{
d += 1000;
return;
}
i += 1000;
if (i > 2147480000)
{
d = i;
usedecimal = true;
}
}
public void SetValue(decimal d)
{
try
{
i = (int)d;
}
catch (OverflowException e)
{
this.d = d;
}
}
public decimal GetValue()
{
return Math.Max(i,d);
}
}
}
My question is the following :
This seems sth. I have been missing, but this must be the bleeding obvious. Can anyone help me out with this?
Are there guidelines for mixed representations, when to use them, when not?
How to have a hunch when a mixed represtenation can be faster without benchmarking?
Any examples?
Any patterns?
Any ideas on the matter?
If you have a type where 99% of the values could be represented in one fast, powerfull type, and only 1% in a very heavy type, (say int vs. BigInteger) How to represent it??
BigInteger implementations typically do exactly that; they keep everything in ints or longs until something overflows, and only then do they go to the heavierweight implementation.
There's any number of ways to represent it. A pattern I like is:
public abstract class Thing
{
private class LightThing : Thing
{ ... }
private class HeavyThing : Thing
{ ... }
public static Thing MakeThing(whatever)
{ /* make a heavy or light thing, depending */ }
... etc ...
}
Are there guidelines for mixed representations, when to use them, when not?
Sure. We can easily compile such a list. This technique makes sense if:
(1) the lightweight implementation is much lighter than the heavyweight implementation
(2) the typical usage falls into the lightweight code path most of the time
(3) the cost of detecting the transition is not a significant cost compared to the cost of the heavyweight solution
(4) the more complex two-representation solution is necessary in order to achieve a customer-focused, realistic performance goal.
How to have a hunch when a mixed represtenation can be faster without benchmarking?
Don't. Making performance decisions based on hunches is reasoning in advance of facts. Drive performance decisions on realistic, customer focused, data-driven analysis, not on hunches. If I've learned one thing about performance analysis over the years its that my hunches are usually wrong.
Any examples?
Any number of implementations of BigInteger.
Any patterns?
Beats the heck out of me. I'm not much of one for memorizing pattern taxonomies.
Any ideas on the matter?
See above.
Perhaps you're looking for the Bridge pattern.
Related
I like to write many small getter properties that describe exactly what they mean.
However this can lead to repeated, expensive calculations.
Every way I know to avoid this makes the code less readable.
A pseudocode example:
ctor(decimal grossAmount, taxRateCalculator, itemCategory)
{
// store the ctor args as member variables
}
public decimal GrossAmount { get { return _grossAmount, } }
private decimal TaxRate { get { return _taxRateCalculater.GetTaxRateFor(_itemCategory); } } // expensive calculation
public decimal TaxAmount { get { return GrossAmount * TaxRate; } }
public decimal NetAmount { get { return GrossAmount - TaxAmount; } }
In this example it is very obvious what each of the properties do because they are simple accessors. TaxRate has been refactored into its own property so that it too, is obvious what it does. If the _taxRateCalculator operation is very expensive, how can I avoid repeated execution without junking up the code?
In my real scenario I might have ten fields that would need to be treated this way, so ten sets of _backing or Lazy fields would be ugly.
Cache the value
private decimal? _taxRate = null;
...
private decimal TaxRate
{
get
{
if (!this._taxRate.HasValue) {
this._taxRate = _taxRateCalculator.GetTaxRateFor(_itemCategory);
}
return this._taxRate.Value;
}
}
You could create a method which will recalculate your values every time you call here.
The advatage of this solution is
you can recalculate your Properties manually
you can implement some sort of Eventlistner which could easy call your recalculation anytime something happends
.
ctor(decimal grossAmount, taxRateCalculator, itemCategory)
{
// store the ctor args as member variables
recalculate();
}
public decimal GrossAmount { get; private set; }
public decimal TaxAmount { get; private set; }
public decimal NetAmount { get; private set; }
public void recalculate();
{
// expensive calculation
var _taxRate = _taxRateCalculater.GetTaxRateFor(_itemCategory);
GrossAmount = grossAmount;
TaxAmount = GrossAmount * _taxRate ;
NetAmount = GrossAmount - _taxRate;
}
Profile. Find out where the application is spending most of the time, and you'll have places to improve. Focus on the worst offenders, there's no point in performance optimizing something unless it has significant impact on the user experience.
When you identify the hotspots, you've got a decision to make - is the optimization worth the costs? If it is, go ahead. Having a backing field to store an expensive calculation is quite a standard way of avoiding repeated expensive calculations. Just make sure to only apply it where it matters, to keep the code simple.
This really is a common practice, and as long as you make sure you're consistent (e.g. if some change could change the tax rate, you'd want to invalidate the stored value to make sure it gets recalculated), you're going to be fine. Just make sure you're fixing a real performance problem, rather than just going after some performance ideal =)
I don’t think there is a way. You want to cache data without a cache. You could build caching functionality into your GetTaxRateFor(…) Method, but I doubt that this is the only expensive method you call.
So the shortest way would be a BackingField. What I usually do is this:
private decimal? _backingField;
public decimal Property { get { return _backingField ?? (_backingField = expensiveMethode()).Value; } }
I've been wondering for a while why C# doesn't support const on a class or a method level. I know that Jon Skeet have wanted support for immutability for a long time, and I recon that using the C++ syntax of function const could aid in that. By adding a const keyword on a class level we would have total support.
Now, my question is, what the reason is for the C# team to not have developed this kind of support?
I'd imagine everything could be created with a compile-time check or through attributes, without needing to change the CLR. I don't mind code being able to override the const behavior through reflection.
Imagine this:
const class NumberContainer
{
public int Number { get; }
}
.. Such a class could only be populated at construction time, so we'd need a constructor to take in an int.
Another example is const on a method-level:
public int AddNumbers(NumberContainer n1, NumberContainer n2) const
{
return n1.Number + n2.Number;
}
Const-level methods should not be able to alter state in their own class or instances of reference types passed to them. Also, const-level functions could only invoke other const-level functions while in their scope.
I'm not really sure if lambdas and delegates would make everything too hard (or impossible) to achieve, but I'm sure someone with more experience in language and compiler design could tell me.
As Steve B pointed out in the comments, the existence of readonly makes things a bit more complex, as const and readonly are close to the same during runtime, but readonly values can't be determined during compile-time. I guess we could have const and readonly level but that might be too confusing?
So, what's the reason for not implementing this? Usability concerns (understanding constness in C++ usually quite hard for new users), language design concerns (can't be done) or simply priority concerns (the days of the immutability-buzz are over)..?
Risking a somewhat circular explanation, C# doesn't support const because the CLR has no support for it whatsoever. The CLR doesn't support it because it is drastically non-CLS compliant.
There are very few languages that have the concept. The C language has support for const, that's well supported in C# by readonly keyword. But the big dog is of course C++ that has a much wider applicability for const, no doubt the one you are looking for. I'll avoid pinning down what const should mean, that's a wormhole in itself and just talk of "const-ness", the property of having const applied.
The trouble with const-ness is that it needs to be enforced. That's a problem in C# when an arbitrary other language can use a C# class and completely ignore const-ness just because the language doesn't support it. Bolting it onto every other CLS language just because C# supports it is of course very unpractical.
Enforceability is a problem in C++ as well. Because the language also supports const_cast<>. Any client code can cast the const-ness away swiftly and undiagnosably. You are not supposed to, but then sometimes you have to. Because there are two kinds of const-ness, strict and observable. Roughly analogous to private const-ness and public const-ness. The mutable keyword was added to the language later to try to deal with the need for observable const-ness so at least the inevitable usage of const_cast<> could be avoided. Some people say that C++ is a difficult language. Don't hear that of C# much.
You say the CLR wouldn't need to be changed, but consider that there's no standard way to express this "const"ness within compiled assemblies - and that these assemblies might not be consumed by C# code anyway. It's not something you can just do for C# - you'd have to do it for all .NET languages.
As I believe the case to be, const means different things in C# compared to C++.
In C# you can use the readonly keyword to get the level of functionality you're wanting from const.
I was once surpised by the following situation:
class Vector
{
private double[] m_data;
public int Dimension {get;set;}
public double this[int i]
{
get {return m_data[i];}
set {m_data[i] = value;}
}
public Vector(int n)
{
this.Dimension = n;
this.m_data = new double(n);
}
public static Vector Zero(int n)
{
Vector v = new Vector(n);
for (int i = 0; i < n; i++)
{
v[i] = 0.0;
}
return v;
}
public static readonly Vector Zero3 = Zero(3);
}
Thou Vector.Zero3 is readonly and you cannot assign to it, you can still access its component, and then the following stupid thing happens:
Vector a = Vector.Zero3;
a[0] = 2.87;
and now, since a ist nothing but a reference to Vector.Vector3 the latter also has Vector.Vector3[0] == 2.87!
After I fell into this pit once, I invented a very simple hack, though not being elegant, fulfills its function.
Namely, into a class that I suppose to produce static readonly "constants", I introduce a Boolean flag:
class Vector
{
private double[] m_data;
public int Dimension {get;set;}
private bool m_bIsConstant = false;
...
public double this[int i]
{
get {return m_data[i];}
set
{
if (!m_bIsConstant)
{
m_data[i] = value;
}
}
}
...
public static Vector Zero(int n)
{
Vector v = new Vector(n);
for (int i = 0; i < n; i++)
{
v[i] = 0.0;
}
v.m_bIsConstant = true;
return v;
}
...
}
This hack guarantees that your static readonly variable will never be modified.
In the case of your proposal for a const-class, you say:
Such a class could only be populated at construction time, so we'd need a constructor to take in an int
But by making all properties read-only anyway you have already achieved what you've said.
I cannot speak for the C# language designers but maybe the reason of not having const applied to lots of other constructs is because adding it was simply not worth the effort and you can get around the issue in other ways (as described above and in other answers/comments).
I can't tell from your question, how this overloading of the const keyword would be especially beneficial.
Your first example could be rewritten legally as
public class NumberContainer
{
private readonly int number;
public NumberContainer(int number)
{
this.number = number;
}
public int Number
{
get { return number; }
}
}
Perhaps, if the compiler is unable to discern the immutability of this class (I don't know), some attribute could be useful?
In your second example, I do not understand what you are driving at. If a function returns a constant value then it can be replaced with a constant field.
Consider this example, it shows two possible ways of lazy initialization.
Except for being thread-safe, are there any specific advantates of using Lazy<T> here?
class Customer {
private decimal? _balance2;
private static decimal GetBalanceOverNetwork() {
//lengthy network operations
Thread.Sleep(2000);
return 99.9M;
}
public decimal? GetBalance2Lazily() {
return _balance2 ?? (_balance2 = GetBalanceOverNetwork());
}
private readonly Lazy<decimal> _balance1 = new Lazy<decimal>(GetBalanceOverNetwork);
public Lazy<decimal> Balance1 {
get { return _balance1; }
}
}
UPDATE:
Please consider above code as a simple example, data types are irrelevant, the point here is to compare Lazy <T> over standard lazy initialization.
It is semantically more correct.
When you use the Nullable<decimal>, what you say is that the value of null will stand for the "unevaluated" state. Although this is a common conversion, it is still arbitrary. There are million other ways to interpret null, so you should probably explain somewhere (in the documentation or at least as a comment) what null means in this case.
On the contrary, when you use Lazy<decimal>, your intentions are clear.
I am attempting to apply the Strategy pattern to a particular situation, but am having an issue with how to avoid coupling each concrete strategy to the context object providing data for it. The following is a simplified case of a pattern that occurs a few different ways, but should be handled in a similar way.
We have an object Acquisition that provides data relevant to a specific frame of time - basically a bunch of external data collected using different pieces of hardware. It's already too large because of the amount of data it contains, so I don't want to give it any further responsibility. We now need to take some of this data, and based on some configuration send a corresponding voltage to a piece of hardware.
So, imagine the following (much simplified) classes:
class Acquisition
{
public Int32 IntegrationTime { get; set; }
public Double Battery { get; set; }
public Double Signal { get; set; }
}
interface IAnalogOutputter
{
double getVoltage(Acquisition acq);
}
class BatteryAnalogOutputter : IAnalogOutputter
{
double getVoltage(Acquisition acq)
{
return acq.Battery;
}
}
Now, every concrete strategy class has to be coupled to my Acquisition class, which is also one of the most likely classes to be modified since it's core to our application. This is still an improvement over the old design, which was a giant switch statement inside the Acquisition class. Each type of data may have a different conversion method (while Battery is a simple pass-through, others are not at all that simple), so I feel Strategy pattern or similar should be the way to go.
I will also note that in the final implementation, IAnalogOutputter would be an abstract class instead of an interface. These classes will be in a list that is configurable by the user and serialized to an XML file. The list must be editable at runtime and remembered, so Serializable must be part of our final solution. In case it makes a difference.
How can I ensure each implementation class gets the data it needs to work, without tying it to one of my most important classes? Or am I approaching this sort of problem in the completely wrong manner?
Strategy Pattern encapsulates a - usually complex - operation/calculation.
The voltage you want to return is dependent on
pieces of configuration
Some of the acquisition data
So I would put these into another class and pass it to strategy implementors.
Also in terms of serialisation, you do not have serialise the strategy classes, perhaps only their name or type name.
UPDATE
Well, it seems that your implementations need only one piece of the acquisition data. That is a bit unusual for a strategy pattern - but I do not believe it fits Visitor better so strategy is fine. I would create a class which has as property, acquisition data (perhaps inherits from it) in addition to configuration that implementors need.
One thing you could do is use factory methods to construct your Strategies. Your individual strategies can take in their constructor only the individual data elements they need, and the factory method is the only thing that needs to know how to fill in that data given an Acquisition object. Something like this:
public class OutputterFactory
{
public static IAnalogOutputter CreateBatteryAnalogOutputter(Acquisition acq)
{
return new BatteryANalogOutputter(acq.Battery);
}
}
Ok, I hate to not give someone else the credit here, but I found a hybrid solution that works very well for my purposes. It serializes perfectly, and greatly simplifies the addition of new output types. The key was a single interface, IOutputValueProvider. Also note how easily this pattern handles the retrieval of varying ways of storing the data (such as a Dictionary instead of a parameter).
interface IOutputValueProvider
{
Double GetBattery();
Double GetSignal();
Int32 GetIntegrationTime();
Double GetDictionaryValue(String key);
}
interface IAnalogOutputter
{
double getVoltage(IOutputValueProvider provider);
}
class BatteryAnalogOutputter : IAnalogOutputter
{
double getVoltage(IOutputValueProvider provider)
{
return provider.GetBattery();
}
}
class DictionaryValueOutputter : IAnalogOutputter
{
public String DictionaryKey { get; set; }
public double getVoltage(IOutputValueProvider provider)
{
return provider.GetDictionaryValue(DictionaryKey);
}
}
So then, I just need to ensure Acquisition implements the interface:
class Acquisition : IOutputValueProvider
{
public Int32 IntegrationTime { get; set; }
public Double Battery { get; set; }
public Double Signal { get; set; }
public Dictionary<String, Double> DictionaryValues;
public double GetBattery() { return Battery;}
public double GetSignal() { return Signal; }
public int GetIntegrationTime() { return IntegrationTime; }
public double GetDictionaryValue(String key)
{
Double d = 0.0;
return DictionaryValues.TryGetValue(key, out d) ? d : 0.0;
}
}
This isn't perfect, since now there's a gigantic interface that must be maintained and some duplicate code in Acquisition, but there's a heck of a lot less risk of something being changed affecting the other parts of my application. It also allows me to start subclassing Acquisition without having to change some of these external pieces. I hope this will help some others in similar situations.
Trying to decipher an appropriate OO design to implement. The basic scenario is that you have a PstnNumber which is essentially a 10 digit phone number that always starts with 0 (e.g. 0195550000). A rule has been introduced to allow auto-correcting of a number if the leading 0 is missing (e.g. 195550000).
START EDIT
I realised the original question may have been misunderstood (thankyou kindly to those whom have answered already), so I have edited to try and better explain the scenario.
END EDIT
I started playing with some preliminary concepts and then thought I would ask if there was a more appropriate way to go or do one of these suffice (on some level)?
Concept 1
public class PstnNumber
{
public virtual string Number { get; set; }
public PstnNumber() { }
public PstnNumber(string number)
{
this.Number = number;
}
}
public class AutoFormattedPstnNumber : PstnNumber
{
public override string Number
{
get { return base.Number; }
set { base.Number = value.PadLeft(10, '0'); }
}
public AutoFormattedPstnNumber() : base() { }
public AutoFormattedPstnNumber(string number)
{
this.Number = number;
}
}
Concept 2 (removed)
Concept 3
public class PstnNumber
{
public bool AutoCorrect { get; set; }
private string number;
public virtual string Number
{
get { return (this.AutoCorrect) ? this.number.PadLeft(10, '0') : this.number; }
set { this.number = value; }
}
public PstnNumber() : this(false) { }
public PstnNumber(bool autoCorrect)
{
this.AutoCorrect = autoCorrect;
}
public PstnNumber(string number) : this(false)
{
this.Number = number;
}
public PstnNumber(string number, bool autoCorrect) : this(autoCorrect)
{
this.Number = number;
}
}
I think Concept 1 may violate the Liskov Substitution rule because the subclass changes the behaviour of the Number property (happy to learn if I've misunderstood that).
Any alternative suggestions would be received happily.
do you have to do the autoformatting when the object is instantiated? If not,
what about:
public class PstnNumber
{
public virtual string Number { get; set; }
public PstnNumber() { }
public PstnNumber(string number) { this.Number = number; }
public AutoFormatNumber { get { return Numer.PadLeft(10, '0'); } }
}
avoid getter-setter-surprise
Avoid getters returning a different value than the one accepted by the setter. Imagine the following snippet:
if (input.Value != current.Number)
{
NumberChangedAgain = true;
current.Number = input.Value;
}
A simple solution would be to make PstnNumber immutable:
temp = PstnNumber.FromString(input.Value);
if (temp != current) { ... }
canonical format
If some data has different representations, there is a lot of advantage to storing it in a canonical representation, and move the format conversions to factory functions and getters / formatters. For example, you don't need to test comparison for short vs. long, long vs. short, short vs. short, long vs. long.
different aspects
Do you need the distinction between an "autoformatted" and a "normal" number, or is this merely a question of input and output - i.e.
does display format (short or long) depend on how the number was entered, or on where it is displayed?
is 0195550000 == 195550000 ?
I'd prefer to fold both classes into one if possible (i.e. when "entered with or without 0 can be forgotten"):
public class PstnNumber
{
private string m_number; // always in long format
public static PstnNumber(string s) { ... } // accepts short and long form
public string Number { get { return m_number; } }
public string AutoFormatted { { get { ... } }
}
Otherwise I'd go with Option 3, but always store the long format in m_number.
In Option 1 and Option 2, you aren't preserving the original number anyway, rendering the subclass worthless (except to know that it was autoformatted at some point, which doesn't seem like useful information). The alternative to make these Options more useful would be to format on Get instead of Set.
Option 3 is therefore the preferred pattern out of these three options, but I would also ask - why can't the PstnNumber also simply detect the number of digits, and autoformat accordingly?
If you follow the rules - there is one that says that "each routine (read class) should do only one thing and do it well".
According to that I would make PstnNumber just hold the number, and create some sort of factory that produces the right number.
Doing both in the same class means that you are weaving domain logic and representation. I prefer them separated.
I'd ask why your class name is so cryptic. "Number" is clear to me, and "P" suggests "phone", but what's the "stn" telling me? A few extra keystrokes would make this class more self-documenting.
I'd also ask about the logic of a default constructor that does not initialize the underlying data members to some value. I think a default constructor should have a sensible default value if possible.
I feel like option 1 is overkill. I don't think inheritance is making this model clearer or better. I don't see how it breaks Liskov substitution, which demands that you can use the subclass in any situation that calls for a base class. The methods map 1:1 as far as I can see. How is Liskov violated?
Option 2 says these are two separate classes with no relationship. That doesn't seem right to me.
All this work suggests that your problem will require that you use both classes. You'll have situations where the leading zero is NOT required and others where it is. Is that true? Or are you always going to require the leading zero?
I don't care for any of your options. I'd prefer an interface or a static factory or even modifying the class you have to anything you've suggested. It feels like a mere formatting issue. Do you store the number with the leading zero? If not, maybe it's just a view concern.
Do you have a really strong reason to have a setter and not have your members final? If not, that's probably a bigger problem than any other variation between the three.
So I'd go for a stateless #3 which means making the number final and gettng rid of the autoFormat variable.
For simplicity I'd just have a getNumberRaw and getNumberFormatted
Better yet, you could have getNumberRaw and getNumber(formatType) where formatType actually contains the code that formats the number since the format may change again in the future and combining formatting (view) with your phone number (model) isn't optimal.
(PS/EDIT): just the fact that a phone number can change is NOT a good reason to have a setter! Creating a new phone number object and replacing the old one will almost always work!
I am not familiar with c#, but I'd do this:
public class PstnNumber {
readonly string number;
public PstnNumber(string number) {
this.number = number;
}
public string getNumber() {
return number;
}
static public PstnNumber createNumber(string number) {
return new PstnNumber(number.PadLeft(10, '0'));
}
}
Of course if I knew how Properties work, I'd probably do it differently :)
I would go with a much simpler version, overriding the ToString method, or even, creating an ToString overload that receives the bool parameter indicating that the number should be formatted.