I have just finished publishing my latest free plugin, called Watermark plugin for jQuery.
The new project has been released on the Google Code site, and the link to the project home page is: http://jquery-watermark.googlecode.com/
The plugin makes it simple to add those little light gray tips inside text entry spaces on a Web page. For example:

The minified version of the code, which is included in the download package, adds less than 2,000 bytes to the page size, so the effect of the code is practically non-existent.
The project home page has an issue tracking system, so please report any bugs found.
The Watermark plugin can also be found in the jQuery plugin directory: http://plugins.jquery.com/project/jquery-watermark
Here's a scenario faced by practically every developer at one time or another: you want to delete a file, but it refuses to delete because Windows sees the file as "locked" by another user.
Sometimes this can be a real file lock, when a user on a different computer does actually have the file open, or sometimes it can be file-locking "junk" left over when a computer that did have a lock crashed or suddenly closed an application.
There has never been a simple "unlock" command to get rid of the file lock (in order to delete the file), no matter why it's being locked, leading to a cavalcade of utilities to work around the problem.
The classic utilities that you'll come across when searching for keywords like "force delete" are programs that delete the locked file at the next boot.
But what a pain in the neck that is! I refuse to install one of those programs, because I always have many programs running, and a fresh boot, done merely to delete a file, is just too painful.
Over the years this issue has been a major gripe with me, which is why I was so happy to finally find a good solution this evening. And the thing is that the utility has been around since 2006.
The utility is called PsFile, and is a part of the brilliant SysInternals suite of utilities created by Mark Russinovich.
Frustratingly, I've looked through SysInternals in the past seeking this same solution, but I always overlooked PsFile because the option to do the unlocking is so subtlely mentioned in the documentation. It comes off as a utility merely to see who has a file open — not a utility to actually close the file/lock.
In my frustration of trying to unlock a file this evening, I had downloaded PsFile just to give me an idea of who/what was holding the lock. I ran the program and saw the file lock, but then looking back at the documentation I noticed a little "-c" command line option. The documentation states, "-c : Closes the files identified by ID or path." Wow!
I gave the option a try, specifying the ID number of the file (which was shown simply by typing "PsFile" at the command prompt), and the file was instantly closed. Awesome!
The exact syntax of the unlock is:
PsFile 1234 -c (1234 is replaced by the actual file ID, or can be a path name)
The PsFile utility can be found (and downloaded) here: http://technet.microsoft.com/en-us/sysinternals/bb897552.aspx
One of the things I love about all the SysInternals utilities is that there is no installation needed. Just unzip the download and copy the included .exe file to your hard disk, and then run it.
SysInternals is extensive and indispensable, and its home page can be found here: http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx
I hope this helps anyone who's experienced a similar problem!
I came across a major performance issue in the Microsoft ASP.NET AJAX client library (JavaScript library) today.
Because the nature of the issue is engrained in the client library code, the only way around it was to completely abandon use of the functions that add, remove, and test for the existence of class names assigned to DOM elements, and develop my own.
Specifically, the following functions are involved/affected:
- Sys.UI.DomElement.addCssClass
- Sys.UI.DomElement.removeCssClass
- Sys.UI.DomElement.containsCssClass
- Sys.UI.DomElement.toggleCssClass
In program code that changes only a few classes here and there, nobody would ever notice performance problems, but when iterating over a large set of DOM elements .... well, that's a different story.
In the process of investigating the performance issues, I took a look at the code behind those functions. I didn't do a bunch of stand-alone, isolated tests to prove my theory (because frankly I don't have the time to do it!), but I believe the problem lies in the containsCssClass function.
Internally, almost every other CSS function calls containsCssClass, so because containsCssClass has a performance issue, it ripples through the other functions as well.
The containsCssClass function does a lot of unncessary work just to find out if a particular element contains a specific class name. It performs a JavaScript split call on the string, then goes through the newly-created array one element at a time to look for a match. But in doing that, it makes various function calls, performs redundant typeof checks — and performs a case-sensitive test on the class name!
So if you perform many addCssClass calls in a loop, you're actually performing lots and lots of expensive calls involving dynamically-created strings and arrays, as well as unnecessary type- and bounds-checking, hurting not only performance, but memory usage.
The case-sensitive matching is also a problem for me, because CSS class names are not case-sensitive by definition. The class name "MyClass" should be able to match with "myclass", but it would not match when using addCssClass, so you could end up having multiple copies of the same class name in a DOM element.
removeCssClass also suffers from case-sensitive matching. Not good.
Another potential problem I found when looking at the Microsoft code is that it does not account for the possibility that a class name appears in the element more than once. It may be a mistake on the part of a developer to do that, but it happens, and it should be accounted for.
For example, given the class name "customer gold vip gold", if you execute the function call Sys.UI.DomElement.removeCssClass(element, "gold"), the new class name will become "customer vip gold". See how the class "gold" is still included in the string, even though you removed it? That's because only the first instance of "gold" was removed.
Last, I hope Microsoft does something about those lengthy namespaces. Having the CSS class manipulation functions nested 4-levels deep in a namespace hierarchy is just plain inefficient and verbose. Maybe they will fix that problem in .NET 4.0.
Function Rewrites
Someday — probably not too distant in the future — I'll be converting much of my code to take advantage of jQuery, but until that time, the solution for this type of problem is to rewrite the code myself.
The end result of my efforts were very easy to measure: a loop that modifies many class names, which was taking 15 seconds to run, now takes 1 second to complete.
I also threw in an extra function that allows class names to be removed with a regular expression (Regex) instead of a fixed string. (This is useful in cases such as when you want multiple class names removed. It can now be accomplished with one function call.)
My new program code for CSS manipulation is shown below.
In the code, I have wrapped the functions in a global object called "DOM", so calling the functions is accomplished like this: DOM.addCssClass(...).
Of course, the global object ("DOM") can be called anything. I personally like using short names for heavily-used global objects, because it keeps code tighter and more legible.
var DOM = {
addCssClass: function (element, className, noTest) {
if ((noTest) || (!DOM.containsCssClass(element, className))) {
element.className = (element.className + " " + className).trim();
}
},
containsCssClass: function (element, className) {
return ((" " + element.className.toLowerCase() + " ").indexOf(" " + className.toLowerCase() + " ") >= 0);
},
removeCssClass: function (element, className, noTest) {
DOM.removeCssClassRegex(element, new RegExp("(^| )" + className + "($| )", "gi"), noTest);
},
removeCssClassRegex: function (element, classRegex, noTest) {
if ((noTest) || (classRegex.test(element.className))) {
element.className = element.className.replace(classRegex, " ").replace(/\s{2,}/g, " ").trim();
}
},
toggleCssClass: function (element, className) {
if (DOM.containsCssClass(element, className)) {
DOM.removeCssClass(element, className, true);
return false;
}
else {
DOM.addCssClass(element, className, true);
return true;
}
}
}
The above code is also available for download.
Designed for Speed
A few key points about the design of the new CSS class name manipulation code:
- There are built-in ways to ensure that the testing of values and class names is only done once per call. In addCssClass, setting the noTest argument to true signifies that the class name definitely does not exist in the element, and the containsCssClass function call is skipped. In removeCssClass, the noTest argument set to true indicates that the class name does exist, without the need to test again.
- containsCssClass does its testing using a simple indexOf string function, which is very fast. It also performs a case-insensitive test, which, as stated above, is an important omission on Microsoft's part.
- removeCssClass now removes all instances of the given class name, not just the first one. It accomplishes the removal with a very simple regular expression (Regex), which is also efficiently used to test for the existence of the class name (if noTest is not true). Sometimes an efficient regular expression pattern can outperform a bunch of string manipulation, depending on what you're trying to do.
- A "bonus" function was added, removeCssClassRegex, which can remove class names by specifying a regular expression instead of a fixed string. For example, to remove both "gold" and "vip" class names from an element, you would call: DOM.removeCssClassRegex(element, /(^| )(gold|vip)($| )/gi);
Are there ways of making the code even faster? Possibly. But probably not by the orders of magnitude that I've just increased it by. Also, one has to balance performance with clarity of the code, which can sometimes suffer when the only objective is performance.
Generally speaking I like what Microsoft has done with its ASP.NET AJAX client library. It's a pretty amazing achievement.
At the same time, it's always good to recognize the parts that need improvement. Microsoft is doing a good job of listening to its community of developers these days, so I'll continue trying to point out things like this whenever I can, in the hope that they get noticed and fixed.
Lottery Post uses Browserhawk (from Cyscape) to detect browser capabilities, so if a user's web browser does not meet the minimum standards required by the site, they can be shown a detailed message page, with a description of exactly what is under-functional.
When the new Google Chrome Web browser was released in the past week, Browserhawk did not detect the new browser properly (and still does not), so users of the new browser had problems logging in to the site.
Since Chrome uses the Apple WebKit open source codebase as its foundation, Browserhawk mistakenly detected the browser as Safari 1.0.
To remedy the situation — at least until Cyscape updates their browser definitions — I have re-programmed the main browser definition file to detect the Chrome browser as Safari 3.1. (Under the covers the Chrome rendering engine is Safari 3.1.)
For anyone else who uses Browserhawk for browser detection, adding Chrome to the browser definitions is fairly straight-forward:
- Open the Browserhawk Editor.
- Select File, Open..., and then select maindefs.bdf and click Open.
- Right-click on the Safari folder (in the left folder/browser list), and click Add... in the context menu.
- In Browser Description enter Chrome.
- In Identifying user agent string enter Mozilla/*AppleWebKit/[5-9][0-9][0-9]*Chrome*Safari*.
- Click OK.
- Change Majorver to 3.
- Change Minorver to 1.
- Change Version to 3.1.
- Change Fullversion to 3.1.
- Make sure the rest of the properties match the properties in the Safari v3 entry by clicking back and forth between Chome and Safari v3 — except for the last two properties.
- Set Versionposx to 0 [zero].
- Set Versionposstr to an empty string.
- Click the Save icon in the editor toolbar to finish the process.
To test to be sure Chrome is being properly identified as Safari 3.1, go to www.mybrowserinfo.com and click on See Detailed Location and Browser Information.
In addition to seeing that it is correctly identified, also be sure cookies and JavaScript are being detected as "enabled".
When working with the ASP.NET AJAX client library, I find that I occasionally need to use both Function.createDelegate() and Function.createCallback() simultaneously.
Each time you use one or the other of these methods, the library places a "call wrapper" around your function. Then, when the new delegate (or callback) is called, there are actually two calls being made: the first to the wrapper, and the second when the wrapper calls your function.
By combining the use of both methods, you're now placing two call wrappers around your function, which is fairly inefficient, not to mention that it's not exactly elegant or readable.
Why would you want to combine the two methods?
You'd want to combine them when you want to ensure that this refers to a specific object, and you also want to pass specific arguments ("context") to the function.
For example, let's start with two objects, each containing an array of messages (strings). We also have a function that expects that this will refer to one of the objects, and it will expect to receive the index of the message to display as an argument.
(This is a very contrived example, but it shows the requirement and solution in simple terms. Real-world situations that require the use of both createDelegate and createCallback are more complex.)
var myObject1 = {
messages: ["Red", "Blue", "Black"]
};
var myObject2 = {
messages: ["Audi", "Chevy", "Mitsubishi"]
};
function showAlert(index) {
alert(this.messages[index]);
};
Now, I'll create two delegates/callbacks: one will call showAlert() and display a color, and the other will call showAlert() and display a car type. I'll do this by combining the use of createDelegate and createCallback.
var showColor = Function.createDelegate(myObject1, Function.createCallback(showAlert, 2));
var showCar = Function.createDelegate(myObject2, Function.createCallback(showAlert, 1));
If we were to call showColor(), the user would see the word "Black" appear in a alert window. Likewise, if we were to call showCar(), the user would see the word "Chevy" appear in a alert window.
The significance of what took place here is that both showColor and showCar can be passed as simple function references to an event or method, and they retain not only the calling object context that we desired (this), but also the argument(s) that we needed to pass (the "context"). It allows us to use one single function (showAlert) to satisfy the display requirements of both objects (myObject1 and myObject2).
The problem with the showColor and showCar methods, as written above, is that they are inefficient because they make a total of three calls each time one is called (two wrapper calls plus the actual function call), and looking at the code, it can be difficult to understand what it is doing (i.e., the code lacks readability).
To solve both issues, I have created a new method called Function.createDelegateCallback().
In one step, we can specify a this reference, the function to wrap/call, and arguments ("context") to pass to the function.
The simplest way of creating the new method would have been to create a method that calls Function.createDelegate(this, Function.createCallback(func, args)), which would solve the readability issue, but would do nothing to solve the inefficiency issue.
Instead, I started with the source code for createCallback, and modified it to include the createDelegate functionality, making sure that only one wrapper call would be placed around the function.
Note: the new createDelegateCallback method is added directly to the JavaScript Function object, just like createDelegate and createCallback are today, so it is utilized in exactly the same way.
Update: After some additional testing, I have slightly modified the code below. I am not sure as to the reasons for Microsoft coding the for loop they way they did in createCallback, but I accepted at face value that it was the best way. I now believe it is better below, and my testing bears that out. There is certainly a reason they coded it the way they did; I just can't figure it out.
Additional note: If you want to pass more than one argument to the target function, simply include them after the context argument.
Function.createDelegateCallback = function (instance, method, context) {
/// <param name="instance" mayBeNull="true"></param>
/// <param name="method" type="Function"></param>
/// <param name="context" mayBeNull="true"></param>
/// <returns type="Function"></returns>
return function() {
var l = arguments.length;
if (l > 3) {
var args = [];
for (var i=2; i<l; i++) {
args[i-2] = arguments[i];
}
return method.apply(instance, args);
}
return method.call(instance, context);
};
};
Now that we have the new createDelegateCallback method, we can re-write the methods above to make them more efficient and readable:
var showColor = Function.createDelegateCallback(myObject1, showAlert, 2);
var showCar = Function.createDelegateCallback(myObject2, showAlert, 1);
createDelegateCallback is not something you'll use every day, but if you do a lot of client-side coding with the ASP.NET AJAX client library, you will be glad someday that you have it.
Whether on a individual computer or a server attached to the Internet someplace, people are always looking for better performance of their software.
The first thought that comes to mind is often adding memory or a faster processor, or choosing a faster operating system or web browser.
But many times (perhaps most times) the real culprit for slow performance is the programmer who wrote the software.
As a programmer, my philosophy is that I personally take responsibility for the performance of my programs, rather than require faster hardware or environment. I have found that by forcing myself to think about the efficiency of every piece of code I write, the combined performance savings across an entire application is immense.
Think about it: if you save just a quarter of a second of time serving one page view, you have actually saved about 70 hours of processor time after a million page views. And for a site like Lottery Post that gets many millions of page views a month... well, you can do the math.
With that concept in mind, I'd like to offer some tips about string concatenation that will make your programs more efficient.
String concatenation — the processing of combining strings together — is something that is still slow on many popular platforms. For example, on all versions of Internet Explorer (up until IE8 is released), combining strings is very inefficient. Even in the .NET framework, there are some ways of programming that will result in poor performance.
String Concatenation in .NET
In the .NET framework, whether you're programming in C# or VB, the best way to combine strings is using the String.Concat() method. However, just using String.Concat() is not enough, and here's where the extra efficiency comes into play:
Make sure that all the arguments passed to String.Concat() are strong-typed Strings. Otherwise, an overloaded version of the String.Concat() will be used that accepts all Object arguments, and each value you pass will be boxed to an Object (when passed) and un-boxed from an Object (when concatenated by the method).
When you test the program, it works just fine either way, but if you are using the Object argument version of the String.Concat() method, you are silently leaking performance.
For example, if you want to create a string like "There are 27 pages", the second version shown below is more efficient:
myString = String.Concat("There are ", intPages, " pages")
myString = String.Concat("There are ", intPages.ToString(), " pages")
(Note: I did not use CStr(intPages), I used intPages.ToString(). That's because the CStr() VB function accepts an Object type, which will require boxing/unboxing, whereas I believe an Integer can execute its ToString() method quicker.)
In the first example, all three arguments are treated as Object types, but in the second example, all three arguments are String types, so the compiler chooses the quicker all-String-arguments version of the String.Concat() method.
Why not use VB's string concatenation operator ("&")? Because when you compile your application, the compiler breaks everything down into String.Concat() operations anyway, and you can do a much better job of that than the compiler could. If you ever took a look at some of the code that gets generated for combining strings, you would be amazed at what is actually taking place under the covers.
And by all means, do not using String.Format() for your string concatenation, unless you are actually using the formatting capabilities of the method (i.e., transforming data into another format). Even though it can produce slightly more readable code, String.Format() has lots of overhead that makes it a poor choice.
Programming efficiency
Sometimes if you think about the way the computer is executing the code, rather than how your mind is assembling the string, you can come up with some nice efficiencies.
For example, let's say you're creating the name of an image file based on the value of a couple different variables.
With the variable names shown in <brackets>, the file name will be "icon_<isCircle>_<size>_.<isGif>", where <isCircle> is a boolean (True for "circle", False or "square"), <size> is any integer (such as 16, for a 16 x 16 image), and <isGif> is a boolean (True for "gif", False for "jpg").
Here is how someone would normally code this (using the tips above for String.Concat):
myImage = String.Concat("icon_", If(isCircle, "circle", "square"), "_", size.ToString(), "_.", If(isGif, "gif", "jpg"))
or, in C#, the same thing would be:
myImage = String.Concat("icon_", isCircle? "circle" : "square", "_", size.ToString(), "_.", isGif? "gif" : "jpg");
It will indeed work fine, and for top efficiency it uses the all-String version of the String.Concat() method, but why should you force the computer to combine 6 different strings together, when you can do the same thing by combining only 3 strings together?
The following is functionally equivalent to the first solution, but takes half the work to do:
myImage = String.Concat(If(isCircle, "icon_circle_", "icon_square_"), size.ToString(), If(isGif, "_.gif", "_.jpg"))
or, in C#:
myImage = String.Concat(isCircle? "icon_circle_" : "icon_square_", size.ToString(), isGif? "_.gif" : "_.jpg");
If you were to go through your program code, how many times would you see something similar to the first solution, as opposed to the second? Probably a lot.
JavaScript coding
The same exact approach applies to JavaScript — especially to JavaScript.
As I mentioned earlier, JavaScript is very slow performing string concatenation on IE web browsers, and IE makes up the majority of web browsers in use today. That's a lot of potential for slow code.
Therefore, when writing JavaScript programs be careful anywhere you combine strings, especially when it's done inside a loop.
The reason behind the slow performance is that each time strings are concatenated, a new copy of the string is created in memory, which requires allocating new memory, copying the contents of the old strings, and then releasing the memory from the old strings.
When doing a lot of string concatenation in JavaScript, it is often much better to create an array of string values, and then use an Array.join() method to combine them. Each time a new element is added to an array, you're allocating memory for the new element, but you're not copying the old string value, and you're not releasing memory for the old string.
Here is an example comparing regular string concatenation with array-based concatenation. The example is to create a string containing a comma-separated list of numbers 1 through 100. The second method is much faster than the first.
Method 1: regular string concatenation
var str = "";
for (var i=1; i<=100; i++) {
str += (i + ",");
}
Method 2: combine array elements
var a = [];
for (var i=1; i<=100; i++) {
a[i-1] = i;
}
var str = a.join(",");
Lots of other efficiencies
There are lots and lots of other things that can be done to increase performance of strings and string concatenation. This only scratches the surface.
Hopefully what this does is to show the types of things that you can think about when you're looking to increase the efficiency and performance of your programs.
I wouldn't go crazy doing things that make your code impossible to read, but at the same time don't be afraid to do things that save only a tiny bit of time. As you implement lots and lots of small tweaks, eventually they will combine into a much bigger overall savings.
I am so happy to report that Microsoft made an announcement this morning that its upcoming IE8 web browser will support all current web browser standards as the default browser behavior!
While I knew that IE8 was going to support the current set of web standards, Microsoft's plan to-date was to require web sites to add a special indicator to their HTML code that would "turn on" this support.
The result of that previous plan would have been a confusing mess of web sites, with many inexperienced web developers wondering why their sites did not render properly.
Also, it would have continued the practice of making old, outdated web browser standards the default experience, and once again the onus would be placed on users to figure out which browser to use for what site.
This is going to be an exciting time for web developers, as they will finally be freed of the shackles imposed by IE6 and IE7 — as soon as enough people have migrated to IE8.
I've done some development work recently for the Safari 3.0 web browser, which currently supports many of the upcoming IE8 features, and it is just so incredibly liberating to use the new standards.
Features like rounded borders, multiple background images per object, CSS selectors based on attribute values, multi-column layouts, and much, much more.
The trick is going to be getting a critical mass of people upgraded to IE8 as quickly as possible. Based on the adoption rate of IE7, that will be no easy task. It was only within the past few months that I've noticed more people using IE7 than IE6. Hopefully there will be a compelling reason to upgrade (for users, that is).
Here is a link to Microsoft's announcement:
http://www.microsoft.com/presspass/press/2008/mar08/03-03WebStandards.mspx