I need to update InstrumentInfo class frequently. I update this class from one thread and access (read) from another.
I have Instrument class. For each Instrument class I need to maintain InstrumentInfo:
// omit class Instrument as not improtant
public class InstrumentInfo
{
public string Name { get; set; }
public TradingStatus Status { get; set; }
public decimal MinStep;
public double ValToday;
public decimal BestBuy;
public decimal BestSell;
}
public class DerivativeInfo : InstrumentInfo
{
public DateTime LastTradeDate { get; set; }
public DateTime ExpirationDate { get; set; }
public string UnderlyingTicker { get; set; }
}
// i do have several more subclasses
I do have two options:
- Create only one
InstrumentInfofor eachInstrument. When some field updates, for exampleBestBuyjust update value of this field. Clients should obtainInstrumentInfoonly once and use it during entire application lifetime. - On each update create new instance of
InstrumentInfo. Clients should obtain every time the most recent copy of InstrumentInfo.
With 1 I do need to lock, because decimal DateTime string update is not guaranteed to be atomic. But I don’t need to reinstatiate object.
With 2 I don’t need to lock at all, as reference update is atomic. But I likely will use more memory and I will probably create more work for GC because every time I need to instatiate new object (and initialize all fields).
1 implementation
private InstrumentInfo[] instrumentInfos = new InstrumentInfo[Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
// invoked from different threads
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
lock (instrumentInfos) {
var result = instrumentInfos[instrument.Id];
if (result == null) {
result = new InstrumentInfo();
instrumentInfos[instrument.Id] = result;
}
return result;
}
}
...........
InstrumentInfo ii = GetInstrumentInfo(instrument);
lock (ii) {
ii.BestSell = BestSell;
}
2 implementation:
private InstrumentInfo[] instrumentInfos = new InstrumentInfo[Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
// get and set are invoked from different threads
// but i don't need to lock at all!!! as reference update is atomic
public void SetInstrumentInfo(Instrument instrument, InstrumentInfo info)
{
if (instrument == null || info == null)
{
return;
}
instrumentInfos[instrument.Id] = info;
}
// get and set are invoked from different threads
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return instrumentInfos[instrument.Id];
}
....
InstrumentInfo ii = new InstrumentInfo {
Name = ..
TradingStatus = ...
...
BestSell =
}
SetInstrumentInfo(instrument, ii); // replace InstrumentInfo
So what do you think? I want to use approach 2 because I like code without locks! Am I correct that I do not need lock at all as I just replace reference? Do you aggree that 2 is preferred? Any suggestions are welcome.
No, your option
1is just as likely to cause more load on the GC (by promoting more objects to the next generation).Use the most sensible, maintainable form. In this case, create new objects.
Do not optimize based on what you ‘think’ might be slower. Use a profiler.