Reputation: 10701
I have an abstract class which runs a fairly computationally intensive series of static functions inside several nested loops.
In a small number of these loops, I need to obtain a list of dates which are stored in a comma-separated string in a .settings file. I then parse them into DateTimes and use them.
The issue is, I'm re-parsing these strings over and over again, and this is using up quite a bit of CPU time (obviously). Profiling shows that 20% of the core algorithm is wasted on these operations. If I could somehow cache these in a place accessible by the static functions then it would save me a lot of processing time.
The simplest option would be to parse the list of DateTimes at the very start of computation, and then pass that list to each of the sub-functions. This would certainly cut down on CPU work, but it would mean that the sub-functions would need to accept this list when called outside the core algorithm. It doesn't make intuitive sense why a list of DateTimes would be needed when calling one of the parent static functions.
Another thing to fix it would be to make the class not abstract, and the functions non-static, and store the list of dates, etc, in variables for each of the functions to access. The reason I wanted to have it abstract with static functions is because I didn't want to have to instantiate the class every time I wanted to manually call one of the sub-functions.
Ideally, what I would like to do is to parse the list once and store it somewhere in memory. Then, when I do a subsequent iteration, I can somehow check to see if it's not null, then I can use it. If it's null (probably because I'm in the first iteration), then I know I need to parse it.
I was thinking I could have a .settings file which has the list in it. I would never save the settings file to disk, but it would basically allow for storage between static calls.
I know this is all very messy - I'm just trying to avoid re-writing a thousand lines of static code if feasible.
If you all think it's a terrible idea then I will raise my white flag and re-write it all.
Upvotes: 0
Views: 2540
Reputation: 6216
If the dates are read-only then it's pretty straightforward - declare a static property on a class which loads the values if they don't exist and stores them in a static variable - something like this:
public class DateList
{
private static List<DateTime> mydates = null; // new List<DateTime>(); haha, oops
public static List<DateTime> Current {
get {
if(mydates == null)
{
lock(typeof(DateList)) {
if(mydates == null) {
mydates = LoadDates();
}
}
}
return mydates;
}
}
// thanks to Porges - if you're using .NET 4 then this is cleaner and achieves the same result:
private static Lazy<List<DateTime>> mydates2 = new Lazy<List<DateTime>>(() => LoadDates(), true);
public static List<DateTime> Current2
{
return mydates2.Value;
}
}
this example would then be accessed using:
var dates = DateList.Current
Be careful if the dates are not read-only - then you'll have to consider things in more detail.
Upvotes: 2
Reputation: 30580
Another thing to fix it would be to make the class not abstract, and the functions non-static, and store the list of dates, etc, in variables for each of the functions to access. The reason I wanted to have it abstract with static functions is because I didn't want to have to instantiate the class every time I wanted to manually call one of the sub-functions.
Do this. Classes exist in order to encapsulate state. If you store the cache somewhere static, you'll only make trouble for yourself if/when you want to add parallelism, or refactor code.
I'm not sure what you mean by the second part ("manually call"). Do you mean while testing?
Upvotes: 2