public async Task b1LoadDataStorageFileAsync()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
//b1
for (int i = 0; i < filepaths.Count; i++)
{
StorageFile f = await data.GetFileAsync(filepaths[i]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await r.ReadToEndAsync();
}
}
}
}
public async Task b2LoadDataIsolatedStorage()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = r.ReadToEnd();
}
}
}
}
await TaskEx.Delay(0);
}
public async Task b3LoadDataStorageFileAsyncThread()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
StorageFile f = await data.GetFileAsync(filepaths[i]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await r.ReadToEndAsync();
}
}
}
});
}
public async Task b4LoadDataStorageFileThread()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
StorageFile f = await data.GetFileAsync(filepaths[i]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = r.ReadToEnd();
}
}
}
});
}
public async Task b5LoadDataStorageFile()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
//b5
for (int i = 0; i < filepaths.Count; i++)
{
StorageFile f = await data.GetFileAsync(filepaths[i]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = r.ReadToEnd();
}
}
}
}
public async Task b6LoadDataIsolatedStorageThread()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
await Task.Factory.StartNew(() =>
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = r.ReadToEnd();
}
}
}
});
}
}
public async Task b7LoadDataIsolatedStorageAsync()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await r.ReadToEndAsync();
}
}
}
}
}
public async Task b8LoadDataIsolatedStorageAsyncThread()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await r.ReadToEndAsync();
}
}
}
});
}
}
public async Task b9LoadDataStorageFileAsyncMy9()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
for (int i = 0; i < filepaths.Count; i++)
{
StorageFile f = await data.GetFileAsync(filepaths[i]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await Task.Factory.StartNew<String>(() => { return r.ReadToEnd(); });
}
}
}
}
public async Task b10LoadDataIsolatedStorageAsyncMy10()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
//b10
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await Task.Factory.StartNew<String>(() => { return r.ReadToEnd(); });
}
}
}
}
}
public async Task b11LoadDataStorageFileAsyncMy11()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
for (int i = 0; i < filepaths.Count; i++)
{
await await Task.Factory.StartNew(async () =>
{
StorageFile f = await data.GetFileAsync(filepaths[i]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = r.ReadToEnd();
}
}
});
}
}
public async Task b12LoadDataIsolatedStorageMy12()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
for (int i = 0; i < filepaths.Count; i++)
{
await Task.Factory.StartNew(() =>
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = r.ReadToEnd();
}
}
});
}
}
}
public async Task b13LoadDataStorageFileParallel13()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
List<Task> tasks = new List<Task>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var task = await Task.Factory.StartNew(async () =>
{
StorageFile f = await data.GetFileAsync(filepaths[index]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
String content = r.ReadToEnd();
if (content.Length == 0)
{
//just some code to ensure this is not removed by optimization from the compiler
//because "content" is not used otherwise
//should never be called
ShowNotificationText(content);
}
}
}
});
tasks.Add(task);
}
await TaskEx.WhenAll(tasks);
}
public async Task b14LoadDataIsolatedStorageParallel14()
{
List<Task> tasks = new List<Task>();
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var t = Task.Factory.StartNew(() =>
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[index], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
String content = r.ReadToEnd();
if (content.Length == 0)
{
//just some code to ensure this is not removed by optimization from the compiler
//because "content" is not used otherwise
//should never be called
ShowNotificationText(content);
}
}
}
});
tasks.Add(t);
}
await TaskEx.WhenAll(tasks);
}
}
public async Task b15LoadDataStorageFileParallelThread15()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var task = await Task.Factory.StartNew(async () =>
{
StorageFile f = await data.GetFileAsync(filepaths[index]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
String content = r.ReadToEnd();
if (content.Length == 0)
{
//just some code to ensure this is not removed by optimization from the compiler
//because "content" is not used otherwise
//should never be called
ShowNotificationText(content);
}
}
}
});
tasks.Add(task);
}
await TaskEx.WhenAll(tasks);
});
}
public async Task b16LoadDataIsolatedStorageParallelThread16()
{
await await Task.Factory.StartNew(async () =>
{
List<Task> tasks = new List<Task>();
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var t = Task.Factory.StartNew(() =>
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[index], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
String content = r.ReadToEnd();
if (content.Length == 0)
{
//just some code to ensure this is not removed by optimization from the compiler
//because "content" is not used otherwise
//should never be called
ShowNotificationText(content);
}
}
}
});
tasks.Add(t);
}
await TaskEx.WhenAll(tasks);
}
});
}
public async Task b17LoadDataStorageFileParallel17()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
List<Task<Task>> tasks = new List<Task<Task>>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var task = Task.Factory.StartNew<Task>(async () =>
{
StorageFile f = await data.GetFileAsync(filepaths[index]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
String content = r.ReadToEnd();
if (content.Length == 0)
{
//just some code to ensure this is not removed by optimization from the compiler
//because "content" is not used otherwise
//should never be called
ShowNotificationText(content);
}
}
}
});
tasks.Add(task);
}
await TaskEx.WhenAll(tasks);
List<Task> tasks2 = new List<Task>();
foreach (var item in tasks)
{
tasks2.Add(item.Result);
}
await TaskEx.WhenAll(tasks2);
}
public async Task b18LoadDataStorageFileParallelThread18()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
List<Task<Task>> tasks = new List<Task<Task>>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var task = Task.Factory.StartNew<Task>(async () =>
{
StorageFile f = await data.GetFileAsync(filepaths[index]);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
String content = r.ReadToEnd();
if (content.Length == 0)
{
//just some code to ensure this is not removed by optimization from the compiler
//because "content" is not used otherwise
//should never be called
ShowNotificationText(content);
}
}
}
});
tasks.Add(task);
}
await TaskEx.WhenAll(tasks);
List<Task> tasks2 = new List<Task>();
foreach (var item in tasks)
{
tasks2.Add(item.Result);
}
await TaskEx.WhenAll(tasks2);
});
}
public async Task b19LoadDataIsolatedStorageAsyncMyThread()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
//b19
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await Task.Factory.StartNew<String>(() => { return r.ReadToEnd(); });
}
}
}
});
}
}
public async Task b20LoadDataIsolatedStorageAsyncMyConfigure()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await Task.Factory.StartNew<String>(() => { return r.ReadToEnd(); }).ConfigureAwait(false);
}
}
}
}
}
public async Task b21LoadDataIsolatedStorageAsyncMyThreadConfigure()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
using (var stream = new IsolatedStorageFileStream("/benchmarks/samplefiles/" + filepaths[i], FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filecontent = await Task.Factory.StartNew<String>(() => { return r.ReadToEnd(); }).ConfigureAwait(false);
}
}
}
});
}
}
public async Task b22LoadDataOwnReadFileMethod()
{
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
filecontent = await ReadFile("/benchmarks/samplefiles/" + filepaths[i]);
}
});
}
public async Task b23LoadDataOwnReadFileMethodParallel()
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var t = ReadFile("/benchmarks/samplefiles/" + filepaths[i]);
tasks.Add(t);
}
await TaskEx.WhenAll(tasks);
}
public async Task b24LoadDataOwnReadFileMethodParallelThread()
{
await await Task.Factory.StartNew(async () =>
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var t = ReadFile("/benchmarks/samplefiles/" + filepaths[i]);
tasks.Add(t);
}
await TaskEx.WhenAll(tasks);
});
}
public async Task b25LoadDataOwnReadFileMethodStorageFile()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
filecontent = await ReadStorageFile(data, filepaths[i]);
}
});
}
public async Task b26LoadDataOwnReadFileMethodParallelStorageFile()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
List<Task> tasks = new List<Task>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var t = ReadStorageFile(data, filepaths[i]);
tasks.Add(t);
}
await TaskEx.WhenAll(tasks);
}
public async Task b27LoadDataOwnReadFileMethodParallelThreadStorageFile()
{
StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < filepaths.Count; i++)
{
int index = i;
var t = ReadStorageFile(data, filepaths[i]);
tasks.Add(t);
}
await TaskEx.WhenAll(tasks);
});
}
public async Task b28LoadDataOwnReadFileMethodStorageFile()
{
//StorageFolder data = await ApplicationData.Current.LocalFolder.GetFolderAsync("benchmarks");
//data = await data.GetFolderAsync("samplefiles");
await await Task.Factory.StartNew(async () =>
{
for (int i = 0; i < filepaths.Count; i++)
{
filecontent = await ReadStorageFile(ApplicationData.Current.LocalFolder, @"benchmarks\samplefiles\" + filepaths[i]);
}
});
}
public async Task<String> ReadStorageFile(StorageFolder folder, String filename)
{
return await await Task.Factory.StartNew<Task<String>>(async () =>
{
String filec = "";
StorageFile f = await folder.GetFileAsync(filename);
using (var stream = await f.OpenStreamForReadAsync())
{
using (StreamReader r = new StreamReader(stream))
{
filec = await r.ReadToEndAsyncThread();
}
}
return filec;
});
}
public async Task<String> ReadFile(String filepath)
{
return await await Task.Factory.StartNew<Task<String>>(async () =>
{
String filec = "";
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = new IsolatedStorageFileStream(filepath, FileMode.Open, store))
{
using (StreamReader r = new StreamReader(stream))
{
filec = await r.ReadToEndAsyncThread();
}
}
}
return filec;
});
}
这些基准测试的运行方式如下:
public async Task RunBenchmark(String message, Func<Task> benchmarkmethod)
{
SystemTray.ProgressIndicator.IsVisible = true;
SystemTray.ProgressIndicator.Text = message;
SystemTray.ProgressIndicator.Value = 0;
long milliseconds = 0;
Stopwatch w = new Stopwatch();
List<long> results = new List<long>(benchmarkruns);
for (int i = 0; i < benchmarkruns; i++)
{
w.Reset();
w.Start();
await benchmarkmethod();
w.Stop();
milliseconds += w.ElapsedMilliseconds;
results.Add(w.ElapsedMilliseconds);
SystemTray.ProgressIndicator.Value += (double)1 / (double)benchmarkruns;
}
Log.Write("Fastest: " + results.Min(), "Slowest: " + results.Max(), "Average: " + results.Average(), "Median: " + results[results.Count / 2], "Maxdifference: " + (results.Max() - results.Min()),
"All results: " + results);
ShowNotificationText((message + ":").PadRight(24) + (milliseconds / ((double)benchmarkruns)).ToString());
SystemTray.ProgressIndicator.IsVisible = false;
}
基准测试结果
这里是原始基准数据的链接:http://www.dehodev.com/windowsphonebenchmarks.xlsx
现在看图表(每个图表显示了通过每种方法加载50次的数据,结果都以毫秒为单位)
下一个1mb的基准测试并不真正代表应用程序。我将它们包含在这里,以便更好地了解这些方法如何扩展。
所以总而言之:用于读取文件的标准方法(1.)始终是最差的(除非您想要读取50个10mb文件,但即使在这种情况下,也有更好的方法)。
我还链接了这个:await AsyncMethod() versus await await Task.Factory.StartNew<TResult>(AsyncMethod),其中认为通常添加新任务没有用处。然而,我在这里看到的结果是你不能假设,应该始终检查是否添加任务可以提高性能。
最后:我想在官方Windows Phone开发者论坛上发布此内容,但每次尝试时都会收到“意外错误”消息...
更新2
结论:
经过审查数据,您可以清楚地看到无论文件大小如何,每个算法都是线性扩展到文件数量。因此,为了简化一切,我们可以忽略文件数量(我们将仅使用50个文件的数据进行未来比较)。
现在讨论文件大小:文件大小很重要。当我们增加文件大小时,算法开始收敛。在10MB文件大小时,前一个最慢的算法占据8个中的4个位置。然而,由于这个问题主要涉及手机,应用程序读取具有这么多数据的多个文件非常罕见,即使是1MB文件对于大多数应用程序也很少见。我的猜测是,即使读取50个20kb的文件也不常见。大多数应用程序可能正在读取0.5kb到3kb大小范围内的数据。(这只是一个猜测,但我认为可能是准确的)
ConfigureAwait()
在 WP 上是存在的,但方法必须返回一个Task
,但我注意到一些 Stream 方法不返回Task
。在循环中等待会导致轻微的性能损失,因为不断地上下文切换。 - Neil Turner