Thursday, July 31, 2008

Cuil not so cuil

It's been done to death already but I can't help agreeing with the pundits who say Cuil will not replace Google as the search engine of choice. I did a search for "Doogal Bell" and most of the returned sites were search listings on other sites that linked to my stuff. OK, I could get to my stuff indirectly this way, but it's hardly what I'm after. Doing a search on Google brought up this site, my home page, the Random Pub Finder and my photos on flickr, which is what I'd expect. It did throw up a few useless directory and search listings sites but further down the list. OK, not very scientific, but it's very rare Google gives me unhelpful results so it's still relevant I think.

The Cuil website says "Rather than rely on superficial popularity metrics, Cuil searches for and ranks pages based on their content and relevance". Isn't this the largely discredited method of searching the web that was used by search engines before Google came along? So how's it going to be better now? It was way too easy to game those search engines by just repeating keywords in the text of your page.

Anyway, it'd be nice if somebody did come up with a decent alternative to Google, it's becoming increasingly obvious that they will soon be a monopoly and we all know what monopolies start getting up to...

Tuesday, July 22, 2008

Radiohead - Ceremony

One of my favourite bands* covering one of my favourite songs, what's not to like?

And if you like it, download it with KeepVid (this is mostly a reminder for myself, I'm sure you already know about this website since you're probably much more web savvy than me)

* If you've read one of my previous posts, you may think I don't like them anymore, but their last album has mostly restored my faith. As has this cover.

Saturday, July 19, 2008

Tracking down memory leaks in managed code

I've been spoilt in the past when I've had memory leaks in my applications. I've worked at places where AQTime has been readily available. But I've recently noticed what appeared to be a memory leak in the FreeFlow Administrator and given that it's a free application I can't justify spending cash on a memory profiler. I had a search on the internet for a free memory profiler and downloaded a trial version of .NET Memory Profiler from Scitech. This was pretty sweet but when the trial ran out I was again unable to justify spending money on buying it.

I then thought there might an API available to capture the objects allocated by the .NET runtime but I was unable to find one. I'm guessing there has to be one, since otherwise how would memory profilers work? Perhaps the API is unmanaged or isn't documented, either way I was unable to find it. But what I did find was useful none the less. Shipping with the .NET runtime is a DLL called SOS.DLL that can be used from Visual Studio to debug memory leaks. I won't go into configuring Visual Studio to use the DLL since this post covers this in detail (the post talks about Visual Studio 2005 but it works just as well in 2008). Instead I'll cover the steps needed to track down a memory leak.

First up, set a breakpoint in your app. When you hit the breakpoint and are in the debugger, these are some useful commands that can be typed into the Immediate window.

.load sos - this loads the SOS.DLL so you can now start to use the SOS commands

!DumpHeap -stat - this will show a list of objects created, grouped by their type and ordered by the total amount of memory used by the objects. You need to analyse this list and look for anything that looks suspicious. I generally ignore the .NET types and concentrate on my own types, since it's most likely that these are causing the problems. Also, it's pretty hard to figure out how many .NET type instances would be too many, there may seem to be lots of string objects around but how many should there be? I was suspicious about a class called FolderControl, so decided to dig deeper into the details for that class.

!DumpHeap -type <type name> - this shows the details of each instance of the specified type (you don't need to specify the fully qualified type name, just the class name will do). The most important detail listed here is the address, since this will be used in the next command.

!GCRoot <address> - this looks for references to an object, which can help track down why an object isn't being garbage collected and hence causing a memory leak. I found the output somewhat confusing but I guess it may be useful.

!help - this lists all the commands available. There are many more than the ones mentioned above.

!help <command name> - get more information about a specific command.

In my case, my dynamically created control was hooking into the Application.Idle event and never unhooking the event handler. Since the Application object remains active for the lifetime of the application, my control was never garbage collected. In my experience, a lot of memory leaks in WinForms applications are caused by event handler issues like this.

After all that, I feel like a proper hardcore geek. Time to learn some assembler...

Wednesday, July 09, 2008

IE7 vs FireFox : The never ending debate

I was reading a forum today when I spotted yet another debate about FireFox and IE7. Much like the Windows vs Mac vs Linux debate, this is getting incredibly tedious. Both browsers (along with Safari, Opera et al) do a perfectly good job of letting people browse the web. Both have their plus points (e.g. FireFox has better plug-ins, IE tends to work with more sites) so just let it go, will you?

Much like the OS debates, the thing that really gets my goat is the smug superiority of FireFox users. Look, using a minority web browser does not make you a hip happening person, it just means you use a different browser than the majority of people. It doesn't make you a better person just because you're not using software written by the "evil empire".

For the record, I use IE and FireFox and I'm not hugely excited by either...

Sunday, July 06, 2008

Zoopla - How much is your house currently worth?

Yet another site for the British obsession with house prices. When I first looked, our house was apparently worth £371,039, now it's worth £375,350, who says house prices are falling? (well me for one...). I'm not sure how valuing it to the nearest pound is possible but hey who am I to argue. Perhaps this is the answer for people having trouble selling their homes, put them on the market for a very exact price, thus showing buyers that you're not messing about and know the value of your house precisely. Well, perhaps.

Any talk of the massive inflation in house prices always makes me think of the quote "House prices are a matter of opinion but debt is real". Even though the value of our house has apparently increased way beyond inflation in the 8 years we have been living here, the debt hasn't reduced dramatically. And due to the way mortgages work, we still have to pay the same amount every month. In fact, come November, we'll probably have to pay a whole lot more. So, why is house price inflation good exactly?

Thursday, July 03, 2008

How to escape text in SQL statements

Two things got me thinking about escaping text in SQL statements recently. I had previously thought it was a simple topic that everybody already knew about but given that these two things occurred I can only assume that not everybody knows about why escaping text in SQL is important and how to do it. First people keep ending up on the FreeFlow website because one of the methods in the class library is called SqlEscape, so obviously people want to know how to do it. The implementation is very very simple.

    /// <summary>
    /// Escapes a string so that single quotes are replaced by two quotes for use in SQL expressions.
    /// </summary>
    /// <param name="sql">The string to escape.</param>
    /// <returns>The escaped string</returns>
    public static string SqlEscape(string sql)
      if (sql == null)
        return null;
      return sql.Replace("'", "''");

Second, I got hold of some free PHP code off the web that failed to do any escaping of the text in SQL expressions. I foolishly deployed this to a website without checking the code beforehand. Fortunately I managed to spot the error before any dodgy hacker managed to take advantage of it. In the PHP world, escaping can be done using the mysql_real_escape_string function.

So that covers the how but why is this important? The first, probably least important, reason is that it means queries that include ' in text strings will work. I guess most people come across this problem when they try to enter a name like "O'Connor" into an application and it fails.

The more important issue, particularly with public facing websites, is SQL injection where a hacker can manage to run pretty much any query they like against your database.

There are other ways to solve this problem. Stored procedures and parameterised queries will also do the trick.

The joy of WITH (NOLOCK)

For a long while I thought it odd that reading from a SQL Server database caused the rows that were being read to be locked. Thinking about it for a little longer makes it clear that it's a necessary evil. You don't want some other process to update records as you're reading them, since the results you get back may well be inconsistent. But the thing is this often doesn't matter that much, so long as it's near enough correct. I've only recently come across WITH (NOLOCK) and I think it's wonderful. It's a quick and dirty way to boost the performance of your queries since it means the query can execute without acquiring a lock on the rows you're trying to get hold of.

Opponents of using it will say there are more fundamental problems with your database that could be fixed with some better indices, but sometimes we don't have the time to do proper performance analysis, so a quick fix is welcome. Purists will no doubt look down their noses at using this technique since it's just not the right thing to do. But I don't care, it improves performance for very little cost. Saying that, I do wonder how inconsistent the data may be. For instance, could I read a row that has a half-written text field? I haven't seen anything like this yet but I do wonder if it's possible.