Tuesday, September 29, 2009

Learning a New Language

 

Since I got my Mac, I've been trying to learn Objective-C, Cocoa, Cocoa Touch, Xcode, and the rest of the iPhone development stack.  As I spend more and more time on this, I've noticed some parallels between learning a new programming language and learning a new spoken language. 

A few years back I moved to Central America and, among other things, learned Spanish.  Learning Spanish was a long, slow, difficult process.  At one point in the process (maybe a few months in) I realized that Spanish is not just a literal translation of English.  That is, you can't just translate the words from English to Spanish.  You also can't just translate the grammar from English to Spanish.

Aside from the basic spelling and grammar rules, languages are made up of many things such as styles, idioms, phrases, mannerisms, local accents, dialects, and more.  Because of this, the trick to learning a new language (once you already have a basic understanding of the syntax and grammar) is to try and think in the new language. You want to try and make the dialects and colloquialisms your own.  You don't want to just translate directly as your speaking as this usually leads to pidgin.  You want to fluently express yourself in this new language and be understood as well as possible.

Translating this to learning a new programming language, you can see that just knowing the syntax and APIs of the new language is not enough. When writing code in a new language you want to own that new language.  You want the code to look like it was written by someone fluent and familiar with the language.  This will greatly improve the quality and maintainability of the code. 

This means that when you learn a new programming language, you should learn the coding standards as well.  So when you write code in C#, it should look like C# and should not use hungarian notation.  And when you write code in Objective-C, it should use the Objective-C styles and it shouldn't look like .NET or anything else.  It can be difficult to adjust to different code/language styles but you haven't really learned the new language until you've done so.

Wednesday, September 16, 2009

How much to you trust Microsoft?

 

Being a .NET (Microsoft stack) developer requires a substantial amount of trust in Microsoft.  I have to trust them to stay in business.  I have to trust that having in-depth knowledge of there technologies is a good economic decision for my years ahead.  I have to trust them to fix bugs in there software, trust the quality of their products like IIS, Windows server, Visual Studio, SQL Server, and others, and trust them to support the technologies I use for the foreseeable future.  I have to trust that the web sites I develop will work properly when running on their platform. 

This is a lot of trust.  And Microsoft has been working hard for years to gain it.  But now they are asking for an entirely new level of trust.  With Microsoft's cloud computing services called Azure, Microsoft is asking us to not only trust their software but their hardware as well.  They're now asking us to trust them to take care of all the infrastructure and to trust that everything will work just fine in their hands. 

This is a big step.  And so I wonder if Scott Guthrie's announcement yesterday about putting jQuery and Ajax.NET on their new Ajax CDN is not just an act of goodwill but is also intended to help build trust in Microsoft hosted web content.  Maybe it's a bit of both.

Friday, September 11, 2009

Performance of an Asp.Net Page versus an Http Handler

A coworker recently mentioned to me that he was thinking about using an http handler instead of a page for performance reasons. My first thought was of a quote I saw in a comment on StackOverflow "He who sacrifices correctness for performance deserves neither." I like the quote. But it doesn't really say much about the problem at hand.

My second thought about these options is that I have trouble imagining that the ASP.Net page life cycle's way of calling events and virtual functions would really add much overhead. Especially if these requests will have to communicate with the database. I would think that the cost of calling the database would far outweigh the cost of generating the page.

But talk is cheap. The code for my page is very simple:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PerfTestPage.aspx.cs" Inherits="WebSandBox.PerfTestPage" %>Hello

The code-behind for the page is just an empty partial class declaration. "Hello" is on the same line as the page declaration so I don't end up with extra "\r\n" charecters in my response stream.

The code for the handler is equally simple:

public void ProcessRequest(HttpContext context)
{
context.Response.Write("Hello");
}

After wiring up the page and the handler in IIS I created a seperate project to do the performance testing. The call to get the request does a simple GET request and ensures that the text "Hello" came back on the response.

public static void DoRequest(string url)
{
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
WebResponse response = request.GetResponse();
string resp = (new StreamReader(response.GetResponseStream())).ReadToEnd();
if (resp != "Hello")
throw new Exception();
}

To ensure that the test is fair, I'm going to call each request a bunch of times before actually timing them. This will ensure that I'm not testing calls that are warming up IIS. In addition, this is all locally so network/wire time should not be a factor in this. Here is the test runner:

static void Main(string[] args)
{
var page = "http://localhost/WebSandBox/PerfTestPage.aspx";
InitializeTest(page);
var pageTime = RunTest(page);

var handler = "http://localhost/WebSandBox/PerfTestHandler.axd";
InitializeTest(handler);
var handlerTime = RunTest(handler);

Console.WriteLine("page time: {0} ms", pageTime);
Console.WriteLine("handler time time: {0} ms", handlerTime);

Console.ReadKey();
}

static void InitializeTest(string url)
{
for (int i = 0; i < 20; i++)
{
PerfTester.DoRequest(url);
}
}

static long RunTest(string url)
{
var sw = new Stopwatch();
for (int i = 0; i < 1000; i++)
{
sw.Start();
PerfTester.DoRequest(url);
sw.Stop();
}
return sw.ElapsedMilliseconds;
}

For this test we're executing each request 1,000 times to make the time more significant. Here are the results:


Page (ms per 1,000 requests) Handler (ms per 1,000 requests)
6186 6259
6152 6216
6145 6182
6156 6208
6133 6201
6169 6190
6536 6416
6161 6190
6162 6189
Average 6200 6228

I don't understand why or how the page is faster than the handler. Maybe IIS is doing some kind of caching. Or maybe there was additional traffic and CPU usage on my computer during these tests. But at around 6.2ms per request, I don't see much of a difference.

Also, this test is only for very simple text "Hello". There would of course be additional overhead when using Asp.Net controls on the page. But I would doubt that the overhead of these controls would far outweigh whatever method the handler would use to generate the same HTML. And that's another topic entirely.

The moral of today's story, "measure twice, cut once".

Thursday, September 3, 2009

My new MacBook

 

This Monday I received a MacBook so I could create an iPhone application. 

This is the first time I'm using a Mac since my mom brought home something like this before I was in highschool.  This is also the first time I'll be using a linux type of system since college.  Needless to say I'm very excited.

mymac

I've started playing with it a little.  I downloaded XCode and the iPhone SDK.  You can see in the photo that I learned how to change the background color.  I think this is probably one of the most common things people do right after turning on a new computer for the first time.

After using C# for the last bunch of years, Objective-C is like getting in a time machine and going back 10 years.  So many practices that I've come to take for granted are gone.  I'm doubt I'll ever come to grips with the "NS" prefix for everything. 

At the same time, the MVC framework to Cocoa seems pretty cool.  And the idea of message-passing for dynamic invocation of methods in a strongly typed system is very interesting.

In addition to my thoughts and feelings about the platform, framework, language, hardware, etc. it's also cool to be starting from scratch again.  I barely know how to save a file on the Mac.  I haven't explicitly used a pointer in almost 10 years.  I'm excited to see what the learning curve is like and exactly what programming skills really do transfer between languages, frameworks, etc.  I've been learning F#, haskell, python, and ruby out of personal curiosity but now I have to actually build something in Objective-C.  Should be interesting.

Tuesday, September 1, 2009

Dynamic Stored Procedure Execution

 

With the imminent arrival of the dynamic keyword to C# I think we will be seeing more prototypes of ways of putting dynamic objects to use within .NET.  One interesting use is Phil Haack's method of HTML encoding properties that are predicated with an underscore.  After reading about this I wanted to try creating my own dynamically driven class.

Disclaimer:  I'm still on the fence over the use of dynamic in C#.  I'm not advocating the use of this code.  I just wanted to see if it was possible and what it would look like.

One problem with ORMs is mapping stored procedures.  This is usually a manual process because stored procedures are inherently not typed.  So I was envisioning something along the lines of:

IList<Person> people = DataContext.Sproc.ExecuteGetList<Person>.spGetPeopleByDOB(dob: myDate);

For the purpose of this prototype, I decided not to use any real data context.  That could be added in easily enough.  For now, I'll be rolling my own data layer.

Step 1 - Create a simple DataContext:

image

Step 2 - Create the Sproc class

This class will basically be a factory for different dynamic stored procedure executers.  This way we can easily differentiate between ExecuteScalar, ExecuteNonQuery, getting an object, and getting a list of objects.  For now, I'm going to implement ExecuteScalar<T>:

image

Step 3 - Create the DynamicExecuteScalar<T> class

image

The real magic here is the use of TryInvokeMember.  This is the function that will be invoked at runtime whenever someone calls a method on your DynamicObject.  So when I call myDynamicExecuteScalar.CallingSomeMethod() I'm actually calling TryInvokeMember. 

Inside of TryInvokeMember we use binder.Name to get the name of the method called (eg. "CallingSomeMethod").  Then we use the binder.CallInfo.ArgumentNames and args[] to get a list of named parameters that we can turn into our sql parameters.

Once you have this code wired up, you can get a scalar for any stored procedure from your code simply by calling:

image

And using this as a starting point you can add ExecuteNonQuery, ExecuteGetList<T>, etc.  You can also modify the data context to be more extensible and mockable.