我知道在同一方法中使用return和yield return是不可能的.
这是我想要优化的代码:
- public IEnumerable<TItem> GetItems(int data)
- {
- if (this.isSingleSet)
- {
- return this.singleSet; // is IEnumerable per-se
- }
- else
- {
- int index = this.GetSet(data);
- foreach(TKey key in this.keySets[index])
- {
- yield return this.items[key];
- }
- }
- }
>转换收益率返回部分:
- ...
- else
- {
- int index = this.GetSet(data);
- return this.keySets[index].Select(key => this.items[key]);
- }
>转换返回部分:
- if (this.isSingleSet)
- {
- foreach(TItem item in this.singleSet)
- {
- yield return item;
- }
- }
- else ...
但两者之间存在很大的速度差异.仅使用return语句(换句话说使用Select())要慢得多(比如慢6倍)才能产生返回转换.
题
有没有其他方法让你想到如何编写这个方法?您是否有任何其他建议信息对性能差异有价值?
附加信息
我正在围绕for循环使用秒表来测量两种方法的速度.
- Stopwatch s = new Stopwatch();
- s.Start();
- for(int i = 0; i < 1000000; i++)
- {
- GetItems(GetRandomData()).ToList();
- }
- s.Stop();
- Console.WriteLine(s.ElapsedMilliseconds);
每个循环都在不同的进程中运行,因此垃圾收集或其他任何东西都可能没有性能影响.
>然后我用一个方法版本运行程序
>关闭它
>重写方法并再次运行.
这几次看到可靠的性能差异……
解决方法
使用两个功能.由客户端调用的外部函数执行您不想延迟的所有非惰性位(如参数验证).私人工作者做懒惰的事情:
- public IEnumerable<TItem> GetItems(int data) {
- if (this.isSingleSet) {
- return this.singleSet; // is IEnumerable per-se
- } else {
- return DoGetItems(data);
- }
- }
- private IEnumerable<TItem> DoGetItems(int data) {
- int index = this.GetSet(data);
- foreach(TKey key in this.keySets[index]) {
- yield return this.items[key];
- }
- }