We're pushing log items of type LogEntry
onto a list of type List<LogEntry>
that'll be saved to file at a much later time.
EDIT 1: The reason we don't flush the log to file immediately is that this is in a highly multi threaded app on Windows Phone with isolated storage. Writing to isolated storage is inherently slow, miles away from desktop performance. The overhead of flushing every message immediately actually kills the concurrent state transitions and interactions we want to observe with the logs. END EDIT 1
Assuming we add millions of items to the list during a not too long time interval, would we be better off using a value or reference type for the item, given the below content of the item?
I.e.
internal struct LogEntry
{
public int ThreadId { get; private set; }
public DateTime Timestamp { get; private set; }
public string Message { get; private set; }
public LogEntry(int threadId, DateTime timestamp, string message)
: this()
{
this.ThreadId = threadId;
this.Timestamp = timestamp;
this.Message = message ?? string.Empty;
}
}
or
internal sealed class LogEntry
{
public int ThreadId { get; private set; }
public DateTime Timestamp { get; private set; }
public string Message { get; private set; }
public LogEntry(int threadId, DateTime timestamp, string message)
{
this.ThreadId = threadId;
this.Timestamp = timestamp;
this.Message = message ?? string.Empty;
}
}
Before actually saving the log to file, we're not doing anything to the item list other than adding items. We don't search, remove or enumerate it - just add items.
What say you, does struct
or class
really matter?
EDIT 2: The result of measuring the timing of adding 60000 entries on the UI thread interleaved by queuing in thread pool work items was 65 seconds for the struct
case and 69 seconds for the class
case. Since this difference is small and the class
implementation is slightly cleaner and I have no need for value equality semantics, I've decided to go for the LogEntry
as a class
. END EDIT 2