Oct 22, 2009

Another good reason not to run program by its name in Windows

When searching for executable by its name Windows always looks in:
  • Current working directory
  • Windows system directory (use GetSystemDirectory() to obtain it)
  • Windows directory (use GetWindowsDirectory() to obtain it)
  • Directories listed in PATH environment variable
This list (I will refer to it as search directories) can be expanded with more directories when performing specific tasks.
If name does not contains file extension (for example notepad or attrib), Windows will use glob "name.*" to find file with extension that is listed in PATHEXT environment variable.

It's okay if you need just to run notepad or mspaint from command line. But what if you need to execute some program many times? Well, running it by its name is definitely not your choice. I'll try to explain why.

First of all, one or more search directories can contain very many files (30000 files for example). Second, one or more search directories can be with slow access time (located on network share for example). If both is true, Windows will spend a lot of time just to locate executable to run. And the entire search will be performed again and again every time you ask Windows to execute something by its name.

Here is a simple example. Lets write small dotestiter.bat file and put it into C:\Windows\System32 directory\ (which is in search directories):
@dir /B %1
It can be executed by name (dotestiter) or by its full path (C:\Windows\System32\dotestiter.bat).
We will call it from dotest_name.bat file:
@for /R %%e in (*) do dotestiter "%%e"
And from dotest_full.bat file:
@for /R %%e in (*) do C:\WINDOWS\system32\dotestiter.bat "%%e"
Both files will call dotestiter.bat for every file in current working directory (current working directory is also in the search directories).
Results for network share with 250 files (I mounted it on Z: with net use to be able access it from command line):
  • dotest_name.bat - 34.6 secs
  • dotest_full.bat - 24.3 secs
As you can see, it is much faster to use full executable path instead of its name. For 3000 files it will be required 2 minutes of extra time just to locate the executable to run!

p.s. It is hard to reproduce the same scenario on *nix since shell does not search current working directory for program name.

No comments:

Post a Comment