Share

This is some­thing I’ve men­tioned in my recent AOP talks, and I think it’s wor­thy of a wider audi­ence as it can be very use­ful to any­one who’s obsessed with per­for­mance as I am.

At iwi, we take per­for­mance very seri­ously and are always look­ing to improve the per­for­mance of our appli­ca­tions. In order for us to iden­tify the prob­lem areas and focus our efforts on the big wins we first need a way to mea­sure and mon­i­tor the indi­vid­ual per­for­mance of the dif­fer­ent com­po­nents inside our sys­tem, some­times down to a method level.

For­tu­nately, with the help of AOP and AWS Cloud­Watch we’re able to get a pseudo-realtime view on how fre­quently a method is exe­cuted and how much time it takes to exe­cute, down to one minute intervals:

image

With this infor­ma­tion, I can quickly iden­tify meth­ods that are the worst offend­ers and focus my pro­fil­ing and opti­miza­tion efforts around those par­tic­u­lar methods/components.

Whilst I can­not dis­close any imple­men­ta­tion details in this post, it is my hope that it’ll be suf­fi­cient to give you an idea of how you might be able to imple­ment a sim­i­lar mechanism.

AOP

A while back I posted about a sim­ple attribute for watch­ing method exe­cut­ing time and log­ging warn­ing mes­sages when a method takes longer than some pre-defined threshold.

Now, it’s pos­si­ble and indeed easy to mod­ify this sim­ple attribute to instead keep track of the exe­cu­tion times and bun­dle them up into average/min/max val­ues for a given minute. You can then pub­lish these minute-by-minute met­rics to AWS Cloud­Watch from each vir­tual instance and let the Cloud­Watch ser­vice itself han­dle the task of aggre­gat­ing all the data-points.

By encap­su­lat­ing the logic of mea­sur­ing exe­cu­tion time into an attribute, you can start mea­sur­ing a par­tic­u­lar method by sim­ply apply­ing the attribute to that method. Alter­na­tively, Post­Sharp sup­ports point­cut and lets you mul­ti­cast an attribute to many meth­ods at once, and allows you to fil­ter the method tar­get by name as well as vis­i­bil­ity level. It is there­fore pos­si­ble for you to start mea­sur­ing and pub­lish­ing the exe­cu­tion time of ALL pub­lic meth­ods in a class/assembly with only one line of code!

Cloud­Watch

The Cloud­Watch ser­vice should be famil­iar to any­one who has used AWS EC2 before, it’s a mon­i­tor­ing ser­vice pri­mar­ily for AWS cloud resources (vir­tual instances, load bal­ancers, etc.) but it also allows you to pub­lish your own data about your appli­ca­tion. Even if your appli­ca­tion is not being hosted inside AWS EC2, you can still make use of the Cloud­Watch ser­vice as long as you have an AWS account and a valid AWS access key and secret.

Once pub­lished, you can visu­al­ize your data inside the AWS web con­sole, depend­ing on the type of data you’re pub­lish­ing there are a num­ber of dif­fer­ent ways you can view them – Aver­age, 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 your­self. For instance, it makes sense to keep a his­tory of hourly aver­ages for the method exe­cu­tion times you’re track­ing so that in the future, you can eas­ily see where and when a par­tic­u­lar change has impacted the per­for­mance of those meth­ods. After all, stor­age is cheap and even with thou­sands of data points you’ll only be stor­ing that many rows per hour.

Share

C#

By default, arith­metic oper­a­tions and con­ver­sions in C# exe­cute in an unchecked con­text, you can use the checked key­word to switch a block of code to the checked con­text so that any arith­metic over­flow that occurs in that block of code will cause the Over­flowEx­cep­tion to be thrown:

image

How­ever, the scope of the checked con­text 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 arith­metic over­flow with­out throw­ing any exceptions:

image

This might seem strange at first, but the rea­son for it is that whether or not an excep­tion should be thrown for an arith­metic overflow/underflow is baked into the MSIL code the com­piler gen­er­ates rather than a run­time deci­sion. When the Over­flowInt method above is com­piled, it’s com­piled to NOT throw any excep­tions when an over­flow occurs, there­fore regard­less of where the method is called from no Over­flowEx­cep­tion will be thrown from inside the Over­flowInt method.

How­ever, it is pos­si­ble to change the default behav­iour for a given project by mak­ing a sim­ple change to a project set­ting. Right-click on a project (inside VS) and go into project prop­er­ties, find the Build tab, and click “Advanced…”. In the sub­se­quent pop-up dia­log there’s a ‘Check for arith­metic overflow/underflow’ checkbox:

image

F#

F# uses a dif­fer­ent approach, it uses oper­a­tor shad­ow­ing so that when­ever you open the Checked mod­ule it over­loads the stan­dard arith­metic oper­a­tors to include checks for arith­metic overflow/underflow and throws the Over­flowEx­cep­tion:

 image

Sup­pose if you have the fol­low­ing mod­ule, the func­tion f will not throw excep­tions for arith­metic over­flows because at the point it is defined the arith­metic oper­a­tors have not been over­loaded yet:

image

Sub­se­quently, if you have code that uses this mod­ule, the over­loaded oper­a­tors from the Checked mod­ule will not apply here just because you’ve opened an mod­ule that imports the Checked module:

image

It is pos­si­ble to sim­u­late the behav­iour of the C# checked key­word as Tomas Patricek sug­gested here, although his solu­tion only works for the int type but nonethe­less it gives you a good idea of how one might be able to do so:

image

Share

In C#, you can use the object/collection ini­tial­iza­tion syn­tax like this:

image

The F# equiv­a­lent of object ini­tial­iza­tion is done like this:

image

As for col­lec­tion ini­tial­iza­tion, you have a far more diverse range of tools avail­able to you, for example:

image

You can also cre­ate slices of an exist­ing array:

image

You can even add your own multi-dimensional index­ers to sup­port sim­i­lar behav­iours in your type too!

Update 2012/01/11:

As Robert Pick­er­ing men­tioned in the com­ments, slic­ing is not lim­ited to arrays, it works with other col­lec­tion types too (as long as a Get­Slice exten­sion method is defined on the type, for more infor­ma­tion, see here). For instance, you can use slic­ing on a string like this:

image

With 2D arrays, you can also use a multi-dimensional slicer too:

image

Share

If you’re read­ing this post, you prob­a­bly know about F#’s Units of Mea­sure already, it’s very use­ful when work­ing with real-world units and adds extra safety to code that needs to work with and con­vert from one unit to another.

Here’s a quick snip­pet that shows you how to define and use units-of-measure:

image

This code out­puts the fol­low­ing, note the units asso­ci­ated with the float values:

image

As you can see, units of mea­sure can also be com­pounded by mul­ti­pli­ca­tion or division!

If you have a func­tion that requires a int<m>, you won’t be able to call the func­tion with a nor­mal int, hence pro­vid­ing you with extra pro­tec­tion to ensure the cor­rect­ness of your appli­ca­tion because the unit of a numeric value is now a for­mal con­tract between a func­tion and its caller:

image

Hav­ing said that, there are cases where you want to be able to con­vert between an int and an int<m>. For instance, to pro­vide bet­ter inter­op­er­abil­ity with other .Net lan­guages, as units-of-measure only exists in F# there’s no way to cre­ate a numeric value with units-of-measure in C# (that I’m aware of anyway).

To con­vert from int<m> to int (or any other numeric type) is easy, just do a straight cast:

image

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 mul­ti­ply the value with 1<m> or use the Int32WithMeasure method on the Lan­guagePrim­i­tives core module:

image

Share