C# 通用接口设计与性能
C# Generic Interfaces Design & Performance
我有一个关于通用接口的基本问题。
案例一:
public interface IDataProcesser
{
TOut Process<Tin,TOut>(Tin input);
}
案例二:
public interface IDataProcesser<Tin,TOut>
{
TOut Process(Tin input);
}
情况 1 是否导致 Boxing/UnBoxing?与案例 2 相比,它的性能是否较低。设计通用接口时是否有任何准则?
谢谢,
拉维
方法一比方法二性能更高(至少我的一台笔记本电脑 - 请参阅下面的代码)。然而,这并不是这里真正重要的部分。
如果泛型类型 TIn
和 TOut
对接口或接口上的大多数方法具有某种语义意义,那么您应该在接口.
如果接口上定义的方法中只有一个或几个使用了泛型类型,那么应该在方法上使用泛型描述。
但是,当您特别询问哪个性能更高时,我输入了一些快速代码并进行了测试。令我惊讶的是,第一种方法实际上性能更高。
方法一花费了 3669 毫秒到 运行,而方法 2 花费了 2715。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
namespace Sandbox
{
public interface IDataProcesser
{
TOut Process<TIn, TOut>(TIn input);
}
public interface IDataProcesser2<TIn, TOut>
{
TOut Process(TIn input);
}
class Class1 : IDataProcesser
{
public TOut Process<Tin, TOut>(Tin input)
{
return default(TOut);
}
}
class Class2 : IDataProcesser2<int, long>
{
public long Process(int input)
{
return default(long);
}
}
class Program
{
private static int _loopCount = 1000000000;
static void Main(string[] args)
{
var warmupEquals = false;
var equals1 = false;
var equals2 = false;
for (long i = 0; i < _loopCount; i++)
{
Class1 warmup = new Class1();
var w1 = warmup.Process<int, long>(default(int)) == 0;
warmupEquals = w1;
}
var sw = new Stopwatch();
sw.Start();
for (long i = 0; i < _loopCount; i++)
{
Class1 c1 = new Class1();
var t1 = c1.Process<int, long>(default(int)) == 0;
if (t1)
{
equals1 = true;
}
}
sw.Stop();
Console.WriteLine("Method 1");
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
sw.Start();
for (long i = 0; i < _loopCount; i++)
{
Class2 c2 = new Class2();
var t2 = c2.Process(default(int)) == 0;
if (t2)
{
equals2 = true;
}
}
sw.Stop();
Console.WriteLine("Method 2");
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(warmupEquals);
Console.WriteLine(equals1);
Console.WriteLine(equals2);
Console.ReadLine();
}
}
}
我有一个关于通用接口的基本问题。
案例一:
public interface IDataProcesser
{
TOut Process<Tin,TOut>(Tin input);
}
案例二:
public interface IDataProcesser<Tin,TOut>
{
TOut Process(Tin input);
}
情况 1 是否导致 Boxing/UnBoxing?与案例 2 相比,它的性能是否较低。设计通用接口时是否有任何准则?
谢谢, 拉维
方法一比方法二性能更高(至少我的一台笔记本电脑 - 请参阅下面的代码)。然而,这并不是这里真正重要的部分。
如果泛型类型
TIn
和TOut
对接口或接口上的大多数方法具有某种语义意义,那么您应该在接口.如果接口上定义的方法中只有一个或几个使用了泛型类型,那么应该在方法上使用泛型描述。
但是,当您特别询问哪个性能更高时,我输入了一些快速代码并进行了测试。令我惊讶的是,第一种方法实际上性能更高。
方法一花费了 3669 毫秒到 运行,而方法 2 花费了 2715。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
namespace Sandbox
{
public interface IDataProcesser
{
TOut Process<TIn, TOut>(TIn input);
}
public interface IDataProcesser2<TIn, TOut>
{
TOut Process(TIn input);
}
class Class1 : IDataProcesser
{
public TOut Process<Tin, TOut>(Tin input)
{
return default(TOut);
}
}
class Class2 : IDataProcesser2<int, long>
{
public long Process(int input)
{
return default(long);
}
}
class Program
{
private static int _loopCount = 1000000000;
static void Main(string[] args)
{
var warmupEquals = false;
var equals1 = false;
var equals2 = false;
for (long i = 0; i < _loopCount; i++)
{
Class1 warmup = new Class1();
var w1 = warmup.Process<int, long>(default(int)) == 0;
warmupEquals = w1;
}
var sw = new Stopwatch();
sw.Start();
for (long i = 0; i < _loopCount; i++)
{
Class1 c1 = new Class1();
var t1 = c1.Process<int, long>(default(int)) == 0;
if (t1)
{
equals1 = true;
}
}
sw.Stop();
Console.WriteLine("Method 1");
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
sw.Start();
for (long i = 0; i < _loopCount; i++)
{
Class2 c2 = new Class2();
var t2 = c2.Process(default(int)) == 0;
if (t2)
{
equals2 = true;
}
}
sw.Stop();
Console.WriteLine("Method 2");
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(warmupEquals);
Console.WriteLine(equals1);
Console.WriteLine(equals2);
Console.ReadLine();
}
}
}