Sign in to follow this  

C#: Suggested data structure for storing data for statistics?

Recommended Posts

So in my game I have a class that logs certain datapoints so that I can analyze them statistically (both in-game, for the player to see his stats, and out-of-game, for testing and balancing). For example, I log each time specific units perform a specific task (such as "went to gather wood") to contrast it with others (like "went to gather stone"), so that I can later graph out the data and see what the big picture looks like for units' nondeterministic behavior. I also log statistics that are not counters, such as "average money spent" and I also store temporal data such as "average money spent over time"... each of these per game entity (such as "money spent by Unit#5"... keeping them as different series in a single graph). So basically I have 3 types of data: counters, statistics (so far only average... I use a struct called "Statistics" to accumulate data for this for each datapoint), and statistics over time.

My question is, what is the best data structure in C# to store and represent this type of data? Keep in mind that the data is not just discrete datapoints... as in, I have to fetch existing data points to update them as I log more data.

Originally my thought was to have a List of datapoints for each of the three value types (int for counter, Statistics for stats, Queue for temporal stats) but this is not a good idea because of what I described above. Instead, I currently have three Dictionaries of Dictionaries... but those dictionaries are hard to work with... for example, the one for temporal stats looks like this:

Dictionary< MetricType, Dictionary < string, Queue < Statistic > >

Where MetricType is an Enum corresponding to the specific type of event/statistic I'm logging (such as "MoneyOwnedByUnit")... it corresponds to selecting different charts to look at. The inner Dictionary is the set of "series" where each string is a series (such as "Unit #5") and the Queue stores, say, up to 500 points for the line graph (such as 0,11,55,33,20).

The nice thing about this is that I can store and fetch data in constant time but working with this large dictionary is a bit of a pain, and as I add more types of logging, or want to log more information for each data point, it quickly gets out of hand... when something this ugly shows up in my code, I typically imagine there is a better way. Does anyone know of a more elegant/correct way to store and fetch my statistics data, or is this pretty much the correct approach? Thanks! =)

Too long; didn't read:

Basically looking for a good data structure to store statistics like counters for an event or statistics about game data. I'm using nested dictionaries... doesn't seem like the best approach though, and would welcome better/cleaner alternatives.

Share this post

Link to post
Share on other sites

I might be misunderstanding what you're trying to accomplish, but to me it seems like it might be better to focus on a very precise way of recording the information you want, and then using functions to analyze it on demand. I don't see why you want to record an ongoing, real-time analysis of your data along with the data itself.


So you might track information in general as a KeyValuePair<GameTime, MetricType>, or a custom structure that can hold the same types of information, and then each time an action is taken in the game it gets added to a list for the acting character. As long as the time is recorded along with the other data, you can generate custom lists of data for anything you want to review be it by activity type, activities over any given period of time, or whatever else.


The idea is a very clear and direct data object that stores all of the information you might want to review later, and then pull only the data you want to look at at any given time. This keeps your code design clear and limits its complexity. You have flexibility in how the data is analyzed by writing a routine to cull whatever specific data you want, so you can always write new ones or alter existing ones. But you don't have to change the underlying data structures to do so.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this