When someone tells you, “You’re doin’ it wrong!” There is often a feeling to push back and get defensive. I’ve learned this is a worthless response. So when I was told that formulas should be written in F# not C# I took it to heart and decided to give F# and functional programming a whirl. While the jury is still out on performance, only because I haven’t completely finished my test app, F# has proven to be WAY more readable as far as formulas are concerned, and load time compared to my C# counter example is AWESOME! In this article I will discuss some high level comparisons and my approach so far.
Motivation
Here at InterKnowlogy we pride our selves on our ability to solve problems in the best way possible for our customers while still preserving readable, reusable, and elegant code. One problem that has come up over the last few years has been how to handle formulas. For example, if I have an Excel workbook with multiple sheets each with a set of complex formulas how do we transpose that workbook into code? My former co-worker and friend Kevin Stumpf in collaboration with the IK team developed what we call PDFx or the Property Dependency Framework. PDFx is a great succinct way to allow properties to depend on on properties by leveraging the INotifyPropertyChanged interface and a LINQ esque API. This was revolutionary for us. Instead of needing a completely separate formula calculator we could build our formulas directly into objects. We could create class for each sheet in an Excel workbook and have a property for each cell. This solution is elegant and easy to maintain. Features our previous implementations were not. This also allowed us the amazing capability to validate our formula output directly to cells in Excel. We have increased in productivity and the code is more reliable because of these things.
So what’s the problem? Performance! It’s not a matter of how complex the formula is, C# is lightning fast at math as far as we are concerned. However, each property that depends on another or more requires a property registration full of lambdas. Lambdas are slow, although you wouldn’t know it unless you were trying to call them about 2 Million times. With depth and width of our object model is really the problem here. Sheer number of instances each with N properties causes load time to be slow. Once loaded PDFx is awesome! Formulas run very quick and we have few grips about performance after load, but load time when accessing properties 2 Million times and running lambdas during that time can take about a minute.
Is there a better way? MAYBE! F# is our next attempt.
Why F# and Functional?
Honestly I’ve only started diligently listening to DotNetRocks in the last month. Shame on me I know. BUT! I backtracked some sessions on F# and Functional Programming. BEST… IDEA… EVER!!! I started looking into the capabilities of F# and feel strongly that I needed to get smart on the topic. We’ve been trying to optimize PDFx for some time now and have a few more tricks up our selves, but that doesn’t mean that it’s THE right way to do formulas. It’s certainly a really good one, but best? To be determined. Functional programming seems like a very intuitive way to handle formulas. After listening to how easy it is to parallelize work in F# I was sold. Functional programming forces you to think differently. Everything is immutable by default in F# and therefore the old ways in C# of looping and creating are over. This help preserve the integrity of your formulas and data which sounds great. Plus, would be no need for property registrations or lambdas and therefore load time, in theory, would only be bottlenecked by instantiating C# objects from the database. The question is runtime performance, which is still to be determined.
Approach – C# vs. F# Formula Comparison App
Since PDFx is open source we wanted to find a way to show it off in all it’s glory. We created a sample formula model in Excel and implemented it in C# using PDFx. The effort to create the workbook took longer than the 2 days it took me to implement the software solution. With this example we have been able to recreate the performance conditions that one of our clients has. Which is really great news! Because this means it is the perfect sample to implement in F# to see if it is more performant than it’s C# cousin. So far F# has taken me a longer period of time to implement, but only because it’s a new language. In fact, I already feel confident that I would be WAY faster in F# than in C# when dealing with formulas like this sample. I’m really excited to see the final results and of course the sample app and Excel workbook will be released as proving points. So look forward to more on this subject.
One major difference about using F# vs. C# & PDfx is that PDFx allows the formula model and the UI model to be the same. In F# this is not true. You need separation between your formula model, which is really the formula inputs and functions, and the UI model. For F# the UI model in our sample app has two mechanisms: GetFormulaInputs(), and ApplyFormulaOutputs(). The F# formula model has 2 main calculations that are called easily from C# with the inputs provided by GetFormulaInputs(). The F# formula model spits out outputs which are then applied in C# via the ApplyFormulaOutputs() method. I’m very close to have this working, but wanted to get my initial thoughts out on the matter first.
Stay Tuned
I’ve been super impressed with F# so far and the community using it. I haven’t struggled too terribly yet, but getting into a functional thought process and thinking in F#, a totally new language to me, has been tough. I have high hopes for the possibilities. The F# Language Reference has become my new best friend!