Overload + = efficient handling?
I have some code where I first form trains
(a custom type trains
that contains an array of a custom type Train
). Then I want to add some data records to each object in the array which will be used later. Instead of writing a method, I overloaded the operator +
. I know this is not necessarily meant to use such operator overloading, but I liked the way the code looked!
Anyway, now I feel sane again and am writing a method to accomplish the same task. But an important question arose for me. What's the difference between the following ways to achieve the same result?
Overloading approach
//Add Maintenance History Data (another custom type for storing such data records) to trains
trains += history;
public static Trains operator +(Trains txs, History[] hist)
{
foreach (Train t in txs)
{
t.AddHist(hist.First(x => x.ID == t.ID));
}
return txs;
}
Membership approach
trains.AddHist(history);
public void AddHistory(History[] hist)
{
foreach (Train t in Txs)
{
t.AddHist(hist.First(x => x.ID == t.ID));
}
}
I am assuming there is a cost per assignment in the overloading approach and therefore should stick to the member based approach?
source to share
There isn't much extra runtime overhead - they are both just methods, although static and instance-based, but it's a tiny tiny difference that will overshadow everything else. The bigger issue is the cost of code clarity - is it obvious that an operator exists +
and has this effect? Also, this means that you cannot make a method virtual
for polymorphism.
I would recommend the method AddHistory
simply because it is clearer.
If you want to minimize your runtime costs, you must:
- avoid LINQ if it has to do with capturing (it's not here, but I'm not sure if the code makes sense, if it actually is
hist.First(x => x.ID == t.ID)
, then it has to do with captures, if the array ishist
small, I would probably just do a flat loopfor
every time to find an element, and if it is big I would plot the index outsideforeach
, perhaps viavar index = hist.ToDictionary(x => x.Id);
- Use
AddRange
etc. whenever possible . - make sure
Equals
not using boxing etc. I suspect ithist.ID == t.ID
will be clearer and more efficient
source to share