This is something I’ve mentioned in my recent AOP talks, and I think it’s worthy of a wider audience as it can be very useful to anyone who’s obsessed with performance as I am.
At iwi, we take performance very seriously and are always looking to improve the performance of our applications. In order for us to identify the problem areas and focus our efforts on the big wins we first need a way to measure and monitor the individual performance of the different components inside our system, sometimes down to a method level.
Fortunately, with the help of AOP and AWS CloudWatch we’re able to get a pseudo-realtime view on how frequently a method is executed and how much time it takes to execute, down to one minute intervals:
With this information, I can quickly identify methods that are the worst offenders and focus my profiling and optimization efforts around those particular methods/components.
Whilst I cannot disclose any implementation details in this post, it is my hope that it’ll be sufficient to give you an idea of how you might be able to implement a similar mechanism.
A while back I posted about a simple attribute for watching method executing time and logging warning messages when a method takes longer than some pre-defined threshold.
Now, it’s possible and indeed easy to modify this simple attribute to instead keep track of the execution times and bundle them up into average/min/max values for a given minute. You can then publish these minute-by-minute metrics to AWS CloudWatch from each virtual instance and let the CloudWatch service itself handle the task of aggregating all the data-points.
By encapsulating the logic of measuring execution time into an attribute, you can start measuring a particular method by simply applying the attribute to that method. Alternatively, PostSharp supports pointcut and lets you multicast an attribute to many methods at once, and allows you to filter the method target by name as well as visibility level. It is therefore possible for you to start measuring and publishing the execution time of ALL public methods in a class/assembly with only one line of code!
The CloudWatch service should be familiar to anyone who has used AWS EC2 before, it’s a monitoring service primarily for AWS cloud resources (virtual instances, load balancers, etc.) but it also allows you to publish your own data about your application. Even if your application is not being hosted inside AWS EC2, you can still make use of the CloudWatch service as long as you have an AWS account and a valid AWS access key and secret.
Once published, you can visualize your data inside the AWS web console, depending on the type of data you’re publishing there are a number of different ways you can view them – Average, Min, Max, Sum, Count, etc.
Note that AWS only keeps up to two weeks worth of data, so if you want to keep the data for longer you’ll have to query and store the data yourself. For instance, it makes sense to keep a history of hourly averages for the method execution times you’re tracking so that in the future, you can easily see where and when a particular change has impacted the performance of those methods. After all, storage is cheap and even with thousands of data points you’ll only be storing that many rows per hour.
By default, arithmetic operations and conversions in C# execute in an unchecked context, you can use the checked keyword to switch a block of code to the checked context so that any arithmetic overflow that occurs in that block of code will cause the OverflowException to be thrown:
However, the scope of the checked context is local to the method – i.e. if in your checked block you call another method then that method is not part of your scope and can cause arithmetic overflow without throwing any exceptions:
This might seem strange at first, but the reason for it is that whether or not an exception should be thrown for an arithmetic overflow/underflow is baked into the MSIL code the compiler generates rather than a runtime decision. When the OverflowInt method above is compiled, it’s compiled to NOT throw any exceptions when an overflow occurs, therefore regardless of where the method is called from no OverflowException will be thrown from inside the OverflowInt method.
However, it is possible to change the default behaviour for a given project by making a simple change to a project setting. Right-click on a project (inside VS) and go into project properties, find the Build tab, and click “Advanced…”. In the subsequent pop-up dialog there’s a ‘Check for arithmetic overflow/underflow’ checkbox:
F# uses a different approach, it uses operator shadowing so that whenever you open the Checked module it overloads the standard arithmetic operators to include checks for arithmetic overflow/underflow and throws the OverflowException:
Suppose if you have the following module, the function f will not throw exceptions for arithmetic overflows because at the point it is defined the arithmetic operators have not been overloaded yet:
Subsequently, if you have code that uses this module, the overloaded operators from the Checked module will not apply here just because you’ve opened an module that imports the Checked module:
It is possible to simulate the behaviour of the C# checked keyword as Tomas Patricek suggested here, although his solution only works for the int type but nonetheless it gives you a good idea of how one might be able to do so:
In C#, you can use the object/collection initialization syntax like this:
The F# equivalent of object initialization is done like this:
As for collection initialization, you have a far more diverse range of tools available to you, for example:
You can also create slices of an existing array:
You can even add your own multi-dimensional indexers to support similar behaviours in your type too!
As Robert Pickering mentioned in the comments, slicing is not limited to arrays, it works with other collection types too (as long as a GetSlice extension method is defined on the type, for more information, see here). For instance, you can use slicing on a string like this:
With 2D arrays, you can also use a multi-dimensional slicer too:
If you’re reading this post, you probably know about F#’s Units of Measure already, it’s very useful when working with real-world units and adds extra safety to code that needs to work with and convert from one unit to another.
Here’s a quick snippet that shows you how to define and use units-of-measure:
This code outputs the following, note the units associated with the float values:
As you can see, units of measure can also be compounded by multiplication or division!
If you have a function that requires a int<m>, you won’t be able to call the function with a normal int, hence providing you with extra protection to ensure the correctness of your application because the unit of a numeric value is now a formal contract between a function and its caller:
Having said that, there are cases where you want to be able to convert between an int and an int<m>. For instance, to provide better interoperability with other .Net languages, as units-of-measure only exists in F# there’s no way to create a numeric value with units-of-measure in C# (that I’m aware of anyway).
To convert from int<m> to int (or any other numeric type) is easy, just do a straight cast:
Going the other way is slightly more tricky, you can’t use int<m> to cast an int to an int<m>, but you can either multiply the value with 1<m> or use the Int32WithMeasure method on the LanguagePrimitives core module: