Загрузка файлов в хранилище больших двоичных объектов Azure - Parallel.Foreach работает медленнее, чем Foreach. - PullRequest
1 голос
/ 10 октября 2011

У меня есть следующий код для загрузки формы папки локальное хранилище в хранилище BLOB-объектов, включая само имя папки в имени BLOB-объекта (код основан на некоторых методах, найденных здесь http://blog.smarx.com/posts/pivot-odata-and-windows-azure-visual-netflix-browsing ):

public static void UploadBlobDir(CloudBlobContainer container, string dirPath)
        {
            string dirName = new Uri(dirPath).Segments.Last();

            Parallel.ForEach(enumerateDirectoryRecursive(dirPath), file =>
                {
                    string blobName = Path.Combine(dirName, Path.GetFullPath(file)).Substring(dirPath.Length - dirName.Length);
                    container.GetBlobReference(blobName).UploadFile(file);
                });
        }

и:

private static IEnumerable<string> enumerateDirectoryRecursive(string root)
        {
            foreach (var file in Directory.GetFiles(root))
                yield return file;
            foreach (var subdir in Directory.GetDirectories(root))
                foreach (var file in enumerateDirectoryRecursive(subdir))
                    yield return file;
        }

Этот код работает и загружает папку, как и предполагалось, но для ее завершения требуется очень много времени - требуется 20 секунд для загрузки 25 файлов по 40 КБ ~ каждый. Поэтому я устал заменять параллельный цикл на обычный, например:

foreach (var file in enumerateDirectoryRecursive(i_DirPath))
            {
                string blobName = Path.Combine(dirName, Path.GetFullPath(file)).Substring(i_DirPath.Length - dirName.Length);
                container.GetBlobReference(blobName).UploadFile(file);
            }

Теперь загрузка завершается мгновенно ( 3 секунды Прибл.).

Также важно отметить, что я работаю против эмулятора хранения для разработки.
Parallel.Forech, очевидно, должен быть быстрее. Происходит ли это различие из-за ограничений эмулятора хранилища (а при запуске Parallel будет быстрее) или же я могу ошибаться?

1 Ответ

4 голосов
/ 10 октября 2011

По моему опыту, эмулятор хранилища строго ничего не говорит о производительности, которую следует ожидать (или нет) от фактического хранилища Azure.Эмулятор обычно очень медленный.

Тогда Parallel.Foreach будет быстрее, только если ваш перевод будет с задержкой , а не с I / O.Затем, пожалуйста, обратите внимание, что Parallel.Foreach будет использовать только ваш номер процессора в качестве степени параллелизации по умолчанию.Для процессов, связанных с задержкой, у вас обычно должно быть намного больше потоков, чем обычно, обычно от 4 до 8 потоков на процессор (YMMV).

...