Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#通用接口设计和;演出_C#_.net_Generics_Boxing - Fatal编程技术网

C#通用接口设计和;演出

C#通用接口设计和;演出,c#,.net,generics,boxing,C#,.net,Generics,Boxing,我有一个关于通用接口的基本问题 案例1: public interface IDataProcesser { TOut Process<Tin,TOut>(Tin input); } public interface IDataProcesser<Tin,TOut> { TOut Process(Tin input); } 公共接口IDataProcesser { TOut流程(Tin输入); } 案例2: public interface IDat

我有一个关于通用接口的基本问题

案例1:

public interface IDataProcesser
{
    TOut Process<Tin,TOut>(Tin input);
}
public interface IDataProcesser<Tin,TOut>
{
    TOut Process(Tin input);
}
公共接口IDataProcesser
{
TOut流程(Tin输入);
}
案例2:

public interface IDataProcesser
{
    TOut Process<Tin,TOut>(Tin input);
}
public interface IDataProcesser<Tin,TOut>
{
    TOut Process(Tin input);
}
公共接口IDataProcesser
{
TOut流程(Tin输入);
}
案例1是否会导致装箱/拆箱?与案例2相比,它的性能是否更低。在设计通用接口时,是否有任何规则

谢谢,, Ravi

方法一比方法二性能更好(至少有一个是我的笔记本电脑-见下面的代码)。然而,这并不是这里真正重要的部分

  • 如果泛型类型
    TIn
    TOut
    对接口或接口上的大多数方法具有某种语义意义,则应在接口上包含泛型描述

  • 如果接口上定义的方法中只有一个或几个使用泛型类型,则应在方法上使用泛型描述

  • 但是,当您特别询问哪个性能更好时,我输入了一些快速代码并进行了测试。令我惊讶的是,第一种方法实际上更有效

    方法一的运行时间为3669毫秒,而方法二的运行时间为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();
            }
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用系统诊断;
    使用System.Linq;
    使用System.Runtime.InteropServices.WindowsRuntime;
    使用系统文本;
    使用System.Threading.Tasks;
    名称空间沙盒
    {
    公共接口IDataProcesser
    {
    TOut流程(TIn输入);
    }
    公共接口IDataProcesser2
    {
    TOut流程(TIn输入);
    }
    类别1:IDataProcesser
    {
    公开兜售流程(Tin输入)
    {
    返回默认值(TOut);
    }
    }
    类别2:IDataProcesser2
    {
    公共长流程(int输入)
    {
    返回默认值(长);
    }
    }
    班级计划
    {
    私有静态int_loopCount=100000000;
    静态void Main(字符串[]参数)
    {
    var warmupEquals=假;
    var equals1=假;
    var equals2=假;
    用于(长i=0;i<\u loopCount;i++)
    {
    Class1预热=新的Class1();
    var w1=预热过程(默认值(int))==0;
    温湿度=w1;
    }
    var sw=新秒表();
    sw.Start();
    用于(长i=0;i<\u loopCount;i++)
    {
    Class1 c1=新的Class1();
    var t1=c1。进程(默认值(int))=0;
    if(t1)
    {
    等式1=真;
    }
    }
    sw.Stop();
    控制台写入线(“方法1”);
    控制台写入线(软件延迟毫秒);
    sw.Restart();
    sw.Start();
    用于(长i=0;i<\u loopCount;i++)
    {
    Class2 c2=新的Class2();
    var t2=c2。进程(默认值(int))=0;
    if(t2)
    {
    等式2=真;
    }
    }
    sw.Stop();
    控制台写入线(“方法2”);
    控制台写入线(软件延迟毫秒);
    控制台。写入线(预热);
    控制台写入线(等式1);
    控制台写入线(equals2);
    Console.ReadLine();
    }
    }
    }
    
    这在很大程度上取决于那些
    Tin
    TOut
    的真实类型,不管怎样,只要用一个分析器来测量一下就可以了。了解一下你为什么认为拳击可能会涉及到这里,这会很有趣。这两种方法之间不应该有任何性能差异,即使有,这是否会是影响系统总体性能的重要差异?。你的问题离要求答案还有好几个阶段,到时候你将拥有比这些接口多得多的东西。创建泛型的目的之一是帮助避免装箱。不会发生装箱/取消装箱,因为您正在指定类型。我看不出性能的不足。非常感谢您花时间编写,非常感谢。如果你也热身的话,你认为2级的成绩会提高吗?既然你预热了Class1,处理器会在预热过程中缓存指令吗?不,我认为不会有影响。如果它起到了作用,我会有点惊讶——但是你可以很容易地测试它,但是在你自己的机器上运行代码。毕竟,硬件很重要:)在您的测试中,您在哪里解释了这样一个事实:您正在分配对象并将分配收费到一个时间间隔,但可能在另一个时间间隔内取消分配这些对象?在第一个秒表间隔中可能没有收集,然后在第二个秒表间隔中,收集器停止世界并收集在第一个间隔中分配的所有对象,从而延迟计时。用秒表获得正确的时间归属是相当棘手的。