harriyott.com

Tuesday, January 31, 2006

Foiled!

Recently, I started prototyping a web application. Work was progressing nicely, until a simple FireFox feature stumped me. Without going into details, the foundation of the application was dragging a URL from a (third-party) page into a text box. Unfortunately FireFox currently appends the link text to the URL, which makes it unusable. You can test this by dragging a link (e.g. this one) to the address bar.

Because it's the drag, rather than the drop that does the appending, there's not much I can do about it on a standard text box on a web page. As the target audience is the Web 2.0 types, a Windows client application is a poor compromise. I've got some research to do...

Business models for the 21st century software developer

I've spotted some trends amongst some small software companies recently. By small, I mean a single developer upwards. Due to better development tools and cheaper marketing (i.e. blogs), it's becoming steadily easier to build and distribute software applications. Successful freeware hobby programs become commercial, and ISVs are born. Revenue is generated in different ways:

  • The "Professional" version
  • Selling to a big company
  • Adsense

Professional Version

Once a free product has sufficient following, users start sending in feature requests. A whole bunch of these will then be added to the next version, the professional version, which isn't free any more. The free version is still available, but it won't have the new features.

The excellent CodeSmith followed this route, although I can't find mention of the free version (2.6) on the site any more. The also excellent TimeSnapper is currently free, but a professional deluxe version is planned.

Selling to A Big Company™

Web applications that collect user data are good candidates for this at the moment. If sufficient users add sufficient data, then the data (as well as the users themselves) become valuable to a larger company.

For example, BlogLines has some very useful, and clean, data about weblogs, and a whole load of users. Ask bought BlogLines for a significant amount. Yahoo have bought Flickr and Del.icio.us. Of course, a large web application use considerable bandwidth, server power and time to keep running smoothly, so some sites cover their costs with...

Adsense

A handy one this, in that not much work is needed to set it up. Money should start dribbling in from the outset, unlike the previous two methods that have a long period of costs before any revenue materialises.

Friday, January 27, 2006

Waterfall 2006 - International Conference on Sequential Development

This looks great:

Waterfall 2006 - International Conference on Sequential Development

I wonder if I can get my boss to send me...

Thursday, January 26, 2006

Joel's also writing about usability

I've just read that Joel Spolsky has started writing some articles on usability, which is what I've just started doing. Fortunately, Joel is writing about gadgets and physical things, whereas mine will be about software usability.

I haven't posted any yet, and I'll probably write them all first, then post them one at a time (so it might be a while).

Tuesday, January 24, 2006

Visual Studio Team Edition pricing

We've been using Visual Studion 2005 Beta 2 since it came out. At that time, we decided to use the Team Test unit testing rather than NUnit. I've just read Jonathan Hodgson's post on pricing, which is rather disheartening. Unit testing is the only feature of the Team System version that we need, but the upgrade price is five times higher. In our case, unit testing is going to cost us over £1,100 per developer. It's good and everything, but no better than NUnit and TestDriven.NET, both of which are free (at the moment). It's going to be much cheaper to convert all our tests to NUnit than to upgrade to the Team System version.

I was speaking to Nick Page of Microsoft yesterday, and he said it's a common problem.

Friday, January 20, 2006

Product releases and versioning assemblies

I'd like some help please! I'm trying to find good ways of managing .NET assembly version numbers, in especially when releasing a product. What are the "best practices"? What problems are often encountered? What do you do?

Tuesday, January 17, 2006

"Mesothelioma" is highest paid search term

It seems that "mesothelioma" is the highest paid search term so far this month. I hadn't even heard of it. Now I know what it is, I can see why it's ahead.

Friday, January 13, 2006

System information tool

Another recommendation for some splendid free software: BGInfo. I was introduced to this at my last job, where many PCs would be setup and shipped to clients. BGInfo displays key system information as desktop wallpaper. Information might include IP address, domain, PC name, processor, RAM, disk space etc. I've configured two machines at work to show the Glassmatix hub ID too.

It's particularly useful when using a KVM, or virtual machines. Again, it's free and easy.

Spam filter software

A couple of people recently have mentioned that they tried out some free utilities that I recommended, so I'll recommend another one of my favourites.

K9 is a email spam filter, written by Robin Keir. Being a bayesian filter, it needs a little bit of training initially, but once it has been told which emails are good, and which are bad, then it does a really good job of sorting the wheat from the chaff. On my system, it's currently running at 99.19%. The remaining 0.81% seem to be false negatives, rather than false positives, so I don't miss any emails that I shouldn't.

There's whitelist and blacklist support, which I find really handy, as I have all email addresses for all my domains coming in through it, so I can blacklist random addresses, such as info@, sales@, webmaster@ etc., and always let mails through from my friends, no matter what nonsense they're on about (actually, one or two might get blacklisted soon, if they don't stop sending me jokes and hoax virus warnings ;-] ).

Anyway, I've been using this for over a year, and I'm delighted with it, and recommend you give it a go.

Most amusing blonde joke

I don't usually post things like this, but this is an excellent blonde joke.

SQL Server performance tips

A colleague of mine has been looking at SQL Server performance, and come up with a great set of tips (mostly gleaned from this website):

Does your SQL statement have a WHERE clause?

I know this sounds obvious, but don't retrieve more data than you need. However, less obvious is that even if your SELECT statement retrieves the same quantity of data without a WHERE clause, it may run faster with one.

Is SELECT DISTINCT being used properly?

Again, pretty obvious, but using SELECT DISTINCT where no duplicate records are being returned is an unnecessary performance hit. If you are getting duplicate records, first double check your table joins as this is often the cause and only use the DISTINCT clause if you really need it.

Are you using UNION instead of UNION ALL?

A UNION statement effectively does a SELECT DISTINCT on the results set. If you know that all the records returned are unique from your union, use UNION ALL instead, it is much quicker.

Are your stored procedures prefixed with 'sp_'?

Any stored procedures prefixed with 'sp_' are first searched for in the Master database rather than the one it is created in. This will cause a delay in the stored procedure being executed.

Are all stored procedures referred to as dbo.sprocname?

When calling a stored procedure you should include the owner name in the call, i.e. use EXEC dbo.spMyStoredProc instead of EXEC spMyStoredProc.

Prefixing the stored procedure with the owner when executing it will stop SQL Server from placing a COMPILE lock on the procedure while it determines if all objects referenced in the code have the same owners as the objects in the current cached procedure plan.

Are you using temporary tables when you don't need to?

Although there is sometimes a benefit of using temporary tables, generally they are best eliminated from your stored procedure. Don't assume that retrieving data multiple times is always less efficient than getting the data once and storing it in temporary table as often it isn't. Consider using a sub-query or derived table instead of a temporary table (see examples below). If you are using a temporary table in lots of JOINS in you stored procedure and it contains loads of data, it might be beneficial to add an index to your temporary table as this may also improve performance.

An example of a derived table instead of a temporary table

SELECT COLUMN1, COLUMN2, COUNTOFCOL3
FROM A_TABLE A
INNER JOIN (SELECT COUNT(COLUMN3) AS COUNTOFCOL3, COLUMN2
FROM B_TABLE B
INNER JOIN C_TABLE C ON B.ID = C.ID) ON A.ID = B.ID

Are you using Cursors when you don't need to?

Cursors of any kind slow down SQL Server's performance. While in some cases they are unavoidable, often there are ways to remove them from your code.

Consider using any of these options instead of using a cursor as they are all faster:
  • Derived tables
  • Sub-queries
  • CASE statements
  • Multiple queries
  • Temporary tables
Are your Transactions being kept as short as possible?

If you are use SQL transactions, try to keep them as short as possible. This will help db performance by reducing the number of locks. Remove anything that doesn't specifically need to be within the transaction like setting variables, select statements etc.

Is SET NO COUNT ON being used?

By default, every time a stored procedure is executed, a message is sent from the server to the client indicating the number of rows that were affected by the stored procedure. You can reduce network traffic between the server and the client if you don't need this feature by adding SET NO COUNT ON at the beginning of your stored procedure.

Are you using IN or NOT IN when you should be using EXISTS or NOT EXISTS?

If you are using IN or NOT IN in a WHERE clause that contains a sub-query you should re-write it to use either EXISTS, NOT EXISTS or perform a LEFT OUTER JOIN. This is because particularly the NOT IN statement offers really poor performance. The example below probably better explains what I mean:

e.g. This SQL statement:

SELECT A_TABLE.COLUMN1
FROM A_TABLE
WHERE A_TABLE.COLUMN2 NOT IN (SELECT A_TABLE2.COLUMN2
FROM A_TABLE2)

Could be re-written like this:
SELECT A_TABLE.COLUMN1
FROM A_TABLE
WHERE NOT EXISTS (SELECT A_TABLE2.COLUMN2
FROM A_TABLE2
WHERE
A_TABLE.COLUMN2 = A_TABLE2.COLUMN2)

Do you have a function that acts directly on a column used in a WHERE clause?

If you apply a function to a column used in the WHERE clause of your SQL statement, it is unlikely that the SQL statement will be able to make use of any indexes applied to that column.

e.g.
SELECT A_TABLE.LASTNAME
FROM A_TABLE
WHERE SUBSTRING (FIRSTNAME,1,1) = 'm'

Could be re-written:
SELECT A_TABLE.LASTNAME
FROM A_TABLE
WHERE FIRSTNAME LIKE = 'm%'
Where you have a choice of using the IN or BETWEEN clauses

Use the BETWEEN clause as it is much more efficient

e.g. This SQL statement:

SELECT A_TABLE.NAME
FROM A_TABLE
WHERE A_TABLE.NUMBER IN (100, 101, 102, 103)

Should be re-written like this:
SELECT A_TABLE.NAME
FROM A_TABLE
WHERE A_TABLE.NUMBER BETWEEN 100 AND 103

Are you doing excessive string concatenation in your stored procedure?

Where possible, avoid doing loads of string concatenation as it is not a fast process in SQL Server.

Have you checked the order of WHERE clauses when using AND?

If you have a WHERE clause that includes expressions connected by two or more AND operators, SQL Server will evaluate them from left to right in the order they are written (assuming that no parenthesis have been used to change the order of execution). You may want to consider one of the following when using AND:
  • Locate the least likely true AND expression first. This way, if the AND expression is false, the clause will end immediately, saving time.
  • If both parts of an AND expression are equally likely being false, put the least complex AND expression first. This way, if it is false, less work will have to be done to evaluate the expression.
Have you checked that you are using the most efficient operators?

Often you don't have much of a choice of which operator you use in your SQL statement. However, sometimes there is an alternative way to re-write your SQL statement to use a more efficient operator. Below is a list of operators in their order of performance (with the most efficient first).

  • =
  • >, >=, <, <=
  • LIKE
  • <>



Saturday, January 07, 2006

Coding in half an hour

I've got a website idea that I've been thinking about developing for around a year now, but I haven't got very far with it. A week or so ago I worked out why: I don't use the half hours. Being a full time developer, I code at work for hours at a time, day after day, so my view on coding is that one needs a long stretch to do anything serious.

But I don't get long stretches.

I get the occasional evening where I can spend two or three hours on it, but that's about once a month. If I'm going out in the evening, I tend to think that the whole evening is taken up, when actually it may not be. There may be half an hour or so between getting the children to bed and going out, and maybe another half an hour after getting in before going to bed. I realised that I think something like "well, it's only half an hour, I won't get much done, so I won't bother".

It's true that it takes a while to warm up, but still, I could use the dead time a whole lot better. If I want to get this thing written, I'll have to learn how to write code in half an hour. The first job is probably writing a list of what needs doing (which will take half an hour). Then I'll need to split the tasks into half hour chunks (a few more half hours - I'm not too hot at estimating). Then I can write a few here and there, and get stuff done.

Thursday, January 05, 2006

URLs in code comments

I was looking through a colleague's code today, and noticed a comment:

' Taken from http://www.vb-helper.com/howto_shell_wait.html

I followed the URL, and read an article about the code. Although I do use internet code as a basis for many things I write, I've never thought of putting the URL in the comments before. What a good idea! I think I'll do that in future.

Fourth Sussex geek dinner

Just got back from the geek dinner. I met Sven Latham, founder of Blogwise, which was really interesting. He was saying that having Google Adsense on the site pretty much pays for the site, which got me thinking about the role Adsense is playing in software development.

Google's terms and conditions forbid (and I paraphrase) encouraging people to click on links to boost funds. Nobody actually wants adverts on their site, as far as the cosmetics or usability is concerned, so the only reason to host Adsense is to boost funds. Therefore, simply hosting Adsense can be considered an encouragement to boost funds.

Having come to that conclusion, if there's a useful website or interesting blog that has Adsense, then why not "support" them by clicking on an advert or two, just every now and again? In essense, there isn't much difference between encouraging "false" clicks on one's own site, and "false" clicking on someone else's.

Tuesday, January 03, 2006

Visual Studio has lost project templates

I'm trying to add a new project to my solution, but Visual Studio has forgotten where the project templates are. In the screenshot below, there should be some stuff in the templates list:



I've checked that the templates actually exist in their usual location:

C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ProjectTemplates\CSharp

and had a good old rummage around Google, but to no avail. Does anyone know anything about this?

Update: Having read this MSDN page, I tried running devenv /setup, and they're all back again.