views:

1681

answers:

5

I've seen several suggestions on naming files randomly, including using

System.IO.Path.GetRandomFileName()

or using a

System.Guid

and appending a file extension.

My question is: What is the fastest way to generate a unique filename?

+12  A: 

A GUID would be extremely fast, since it's implementation guarantees Windows can generate at least 16,384 GUIDS in a 100-nanosecond timespan. (As others pointed, out the spec doesn't guarantee, only allows for. However, GUID generation is really, really fast. Really.) The likelihood of collision on any filesystem anywhere on any network is very low. It's safe enough that although it'd be best practice to always check to see if that filename is available anyway, in reality you would never even need to do that.

So you're looking at no I/O operations except the save itself, and <0.2 milliseconds (on a test machine) to generate the name itself. Pretty fast.

Rex M
WOW! Do you have a link source that describes this implementation guarantee?
Dan Esparza
I don't believe Windows gaurantees that it can **generate** 16,384 GUIDS in 100 nS - only that the values produced by the GUID algorithm are gauranteed to have that level of distribution. Besides, using logic, 16k GUIDS per 100-Ns would be 163 billion GUIDS per second ... which means it takes less than 1/10the of a CPU cycle to produce a GUID? That doesn't much make sense.
LBushkin
see this question about GUID uniqueness http://stackoverflow.com/questions/39771/is-a-guid-unique-100-of-the-time
BlackTigerX
This is obviously a theoretical value which guarantees uniqueness of up to 16K Guids per 100 ns. The actual speed cannot be guaranteed by microsoft, since it depends (among other things) on your cpu speed which does not com close to the theoretical limit as pointed out be LBushkin
Manu
@Dan Raymond Chen breaks down the component parts of a GUID (it's not just a random number) here: http://blogs.msdn.com/oldnewthing/archive/2008/06/27/8659071.aspx note the 14-bit uniquifier, which ensures GUIDs generated in the same 100-nanosecond timespan are still one-in-2^14 unique.
Rex M
@LBushkin you're right, that was a poor reading of the spec. However, I stand by the assertion that generating GUIDs is so stupid fast you don't need to bother measuring it.
Rex M
@Rex M: To measure is to know.
LBushkin
@Lbushkin see my update.
Rex M
A: 

That Guid method is pretty quick.

Since it is a good way to (very reasonably) ensure uniqueness, you avoid the need to check if the file exists.

(No HDD access) == (very fast, yes)
John Gietzen
+1  A: 

If you control the destination where the files will be located, and there is only one process and thread that writes to it, just append some auto-incrementing number to a base name.

If you don't control the destination, or need a multithreaded implementation, use a GUID.

LBushkin
While I almost always use GUID for this problem, LBushkin is right about performance. If you really want *every* drop of perf, incrementing an integer and converting it to a string is faster than generating a Guid and converting it to a string... But will only work if you have control of the directory.
Troy Howard
+10  A: 

You want System.IO.Path.GetTempFileName()

Joel Coehoorn
+1 - this is the simplest and best solution.
Noldorin
That actually creates a file. I think you mean System.IO.Path.GetRandomFileName()
Dan Esparza
Dan is correct. It creates a file in the Windows temp directory.
adrianbanks
It does create a file, but I stand by the answer because it will save you having to create it yourself or test for existence/collisions yourself later. And why create the file name if you're not going to use it?
Joel Coehoorn
Three problems with this: 1) No control over the file extension it's always .TMP, 2) No control over the directory where the temp file is created, it's always in TEMP, 3) It uses P/Invoke to have the OS produce the temp file so it's almost certainly not the *fastest* approach, which is what the OP seems to be looking for.
LBushkin
meh: control over the name or the path weren't part of the requirements. And who says P/Invoke is necessarily slow?
Joel Coehoorn
For anyone who uses GetTempFileName (Either in System.IO.Path or the Win32 call) You may want to read the following article to understand weaknesses with this system:http://dotnet.org.za/markn/archive/2006/04/15/51594.aspxAlso, it's likely not the fastest way. Extern calls *are* slow due to the need for marshalling. Making a new Guid involves an internal call to the runtime. I imagine that just passes the call on to the Win32 API for the same (CoCreateGuid or UUIDCreate)...
Troy Howard
+1  A: 

Use an Int and increment it for each file.

Tom B