попробуйте это:
PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out))
While .NET 4.0 provides the lazy Directory.EnumerateFiles
, you can do this right now on .NET 3.5:
The only part that I think you could improve is the dirInfo.GetFiles("*.*")
. In .NET 3.5 and earlier, it returns an array with all the file names, which takes time to build and uses lots of RAM. In .NET 4.0, there is a new Directory.EnumerateFiles
method that returns an IEnumerable
instead, and fetches results immediately as they are read from the disk. This could improve performance a bit, but don't expect miracles...
You should consider using a third party utility to perform the copying for you. Something like robocopy may speed up your processing significantly. See also https://serverfault.com/questions/54881/quickest-way-of-moving-a-large-number-of-files
I'd keep in mind the 80/20 rule and note that if the bulk of the slowdown is .file.CopyTo
, and this slowdown far outweighs the performance of the LINQ query, then I wouldn't worry. You can test this by removing the file.CopyTo
line and replacing it with a Console.WriteLine
operation. Time that versus the real copy. You'll find the overhead of GoGrid versus the rest of the operation. My hunch is there won't be any realistic big gains on your end
EDIT: Ok, so the 80% is the GetFiles
operation, which isn't surprising if in fact there are a million files in the directory. Your best bet may be to begin using the Win32 API directly (like FindFirstFile and family) and P/Invoke:
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
static extern IntPtr FindFirstFile(string lpFileName,
out WIN32_FIND_DATA lpFindFileData);
I'd also suggest, if possible, altering the directory structure to decrease the number of files per directory. This will improve the situation immensely.
EDIT2: I'd also consider changing from GetFiles("*.*")
to just GetFiles()
. Since you're asking for everything, no sense in having it apply globbing rules at each step.
Вы можете поэкспериментировать с использованием (ограниченного числа) потоков для выполнения CopyTo (). Сейчас вся операция ограничена одним ядром.
Это улучшит производительность, только если теперь она привязана к ЦП. Но если это работает на RAID, это может сработать.
Послушайте этот подкаст Hanselminutes . Скотт разговаривает с Аароном Боковером, автором медиаплеера Banshee, они столкнулись с этой конкретной проблемой и рассказали об этом в 8:20 в подкасте.
Если вы можете использовать .Net 4.0, используйте их Directory.EnumerateFiles, как указано в Томас Левеск. В противном случае вам может потребоваться написать собственный код обхода каталогов, как это было в Mono.Posix, с использованием собственных API Win32.