我有以下代码,用于将文件夹形式本地存储上传到 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;
}
此代码可以正常工作并按预期上传文件夹,但需要花费大量时间才能完成 - 上传 25 个文件(每个文件 40KB~)需要20 秒。所以我厌倦了用常规循环替换并行循环,如下所示:
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 显然应该更快。这种差异是否来自存储模拟器的限制(上线时,并行会更快),还是我可能做错了什么?
最佳答案
根据我的经验,存储模拟器不会告诉您任何关于您应该从实际 Azure 存储中期望(或不期望)获得的性能。模拟器通常非常慢。
只有当您的传输碰巧是延迟限制而不是 I/O 限制时,Parallel.Foreach
才会更快。然后,请注意,Parallel.Foreach
只会使用您的CPU数量作为默认并行度。对于受延迟限制的进程,您通常应该拥有比这更多的线程,通常每个 CPU (YMMV) 4 到 8 个线程。
关于azure - 将文件上传到 Azure BLOB 存储 - Parallel.Foreach 比 Foreach 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7710067/