相关疑难解决方法(0)

使用'var'会影响性能吗?

之前我问了一个问题,为什么我看到这么多的例子都使用了这个var关键字并得到了答案,虽然它只是匿名类型所必需的,但它仍然被用来使编写代码"更快"/更容易和"只是因为".

这个链接("C#3.0 - Var不是Objec")之后,我看到它var被编译成IL中的正确类型(你会在中间的文章中看到它).

我的问题是IL代码使用var关键字take 会有多少(如果有的话),如果在任何地方使用它,它是否会接近于对代码性能有可衡量的水平?

c# variables performance var

223
推荐指数
8
解决办法
10万
查看次数

泛型与接口的实际优势

在这种情况下,使用泛型与接口有什么实际优势:

void MyMethod(IFoo f) 
{
}

void MyMethod<T>(T f) : where T : IFoo
{
}
Run Code Online (Sandbox Code Playgroud)

即你能做什么MyMethod<T>,你不能在非通用版本?我正在寻找一个实际的例子,我知道理论上的差异是什么.

我知道,在MyMethod<T>T 中,T将是具体的类型,但是我只能在方法体内将它用作IFoo.那么什么才是真正的优势呢?

c# generics polymorphism

42
推荐指数
4
解决办法
9864
查看次数

Expression.Compile与Lambda的性能,直接与虚拟调用

我很好奇Expression.Compile与代码中的lambda表达式和直接方法使用的性能如何,以及直接方法调用与虚方法调用(伪代码):

var foo = new Foo();
var iFoo = (IFoo)foo;

foo.Bar();
iFoo.Bar();
(() => foo.Bar())();
(() => iFoo.Bar())();
Expression.Compile(foo, Foo.Bar)();
Expression.Compile(iFoo, IFoo.Bar)();
Expression.CompileToMethod(foo, Foo.Bar);
Expression.CompileToMethod(iFoo, IFoo.Bar);
MethodInfo.Invoke(foo, Foo.Bar);
MethodInfo.Invoke(iFoo, IFoo.Bar);
Run Code Online (Sandbox Code Playgroud)

c# performance lambda expression virtual-functions

22
推荐指数
3
解决办法
7106
查看次数

使用具体类型而不是界面是否更好的性能?

我遇到了一些规则(建议)使用混凝土ListDictionary,而不是IListIDictionary给予,显示通过该接口访问样本测试是相当慢一点.例如,将10000个值添加到列表然后Count在列表上执行10亿次表示通过接口执行此操作比通过具体类执行它慢28倍.即,通过具体类需要80ms,通过界面需要2800ms,这表明它通过界面的速度非常慢.鉴于此,使用具体类是合理的.有没有理由说接口这么慢?(可能更多的是针对那些了解更多关于.net内部的人).

.net c# performance

15
推荐指数
3
解决办法
1297
查看次数

属性比字段慢

似乎我遇到的每个帖子都达成了相同的共识:仅返回字段的属性由JIT内联,并且具有与字段几乎相同的性能.

但是,我目前的情况似乎并非如此.我的程序进行密集计算,访问许多属性,这些属性只是自动获取器和私有设置器.但是,在这种特殊情况下,我只是复制一个对象.

在启用优化的情况下在发布模式下分析代码会导致get对属性函数的许多调用.Copy()总呼叫总计约5.6ms.

属性基准

但是,当属性转换为字段时,函数运行速度比使用属性快6倍:

在此输入图像描述

与使用字段相比,比较两个属性的相等性似乎会产生更多的性能损失.这是类IEquatable实现的基准,使用相同的代码,但使用字段交换属性.

在此输入图像描述

如果JIT应该通过内联来优化属性,为什么会出现?我想保留属性,因为它们的访问控制方面非常方便,但如果它们这么慢,我会坚持使用字段.

编辑:似乎受此问题影响的一些(但不是全部)案例正在使用在接口中声明的属性.在这些情况下没有使用其他多态性,但在这些情况下,删除接口会将性能差异带入预期的水平.

编辑2:如前面的编辑​​所述,似乎问题的一部分是由于接口虚拟调用.经过更多调查后,似乎在CLR中运行基准测试正确地内联属性,但JetBrains dotTrace没有,即使选中"启用内联"也是如此.

c# jit field properties

14
推荐指数
1
解决办法
164
查看次数

Where(predicate).FirstOrDefault() vs FirstOrDefault(predicate) 的基准测试令人惊讶还是错误?

我知道这个问题已经被 了很多 ,甚至有人说

所以, first(FirstOrDefault(predicate)) 一个在性能方面更好1

我明白了,我也认为再调用一个方法应该稍微慢一点,这只是我的直觉。尽管如此,我还是决定运行一些基准测试来证明我的权利,而我却知之甚少。

这是我运行基准测试的结果:

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-3630QM CPU 2.40GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.101
  [Host]     : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT
  Job-XMZTSC : .NET Framework 4.8 (4.8.4121.0), X64 RyuJIT
Runtime=.NET 4.7.2  

Method                            N      Mean         Error      StdDev    Ratio    RatioSD
WherePlusFirstOrDefaultArray    10000   31.44 us    0.288 us    0.270 us    0.40    0.00
FirstOrDefaultArray             10000   78.47 us    0.679 us    0.635 us    1.00 …
Run Code Online (Sandbox Code Playgroud)

.net c# linq performance benchmarking

6
推荐指数
1
解决办法
188
查看次数

提高"洗牌"效率

现在,我使用以下代码创建一个Shuffle扩展:

public static class SiteItemExtensions
{
    public static void Shuffle<T>(this IList<T> list)
    {
        var rng = new Random();
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            T value = list[k];
            list[k] = list[n];
            list[n] = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种更快,更有效的方法来做到这一点.现在,使用秒表类,大约需要20秒来洗牌100,000,000件物品.有没有人有任何想法让这更快?

c# extension-methods

5
推荐指数
1
解决办法
371
查看次数

参数和带约束的 T 泛型参数有什么区别?C#

我真的不明白两者之间有什么区别:

private void Send<T>(T packet) where T : IPacket
Run Code Online (Sandbox Code Playgroud)

private void Send(IPacket packet)
Run Code Online (Sandbox Code Playgroud)

既然通用有限制,那不是一模一样吗?如果不是,那么这里的区别是什么?使用带有约束的通用方法相对于简单方法有什么优点?

谢谢!

c# generics parameters

5
推荐指数
1
解决办法
174
查看次数

为什么调用抽象方法比在.NET中使用接口方法更快?

我有一个接口I,一个抽象类A,这两者的具体类,以及一个C用作基线的具体类.

interface I
{
    void Do();
}
abstract class A
{
    public abstract void Do();
}
class C
{
    public void Do() {}
}
class IImpl : I
{
    public void Do() {}
}
class AImpl : A
{
    public override void Do() {}
}
Run Code Online (Sandbox Code Playgroud)

我对基准通话C.Do(),I.Do()A.Do()使用BenchmarkDotNet.

public class Bench
{
    private C _c;
    private I _i;
    private A _a;

    [Setup]
    public void Setup()
    {
        _c = …
Run Code Online (Sandbox Code Playgroud)

.net c# clr performance benchmarking

5
推荐指数
0
解决办法
128
查看次数

接口与抽象性能 C#

假设我有一个包含 3 个方法的接口,即 m1()、m2()、m3(),并且我有一个抽象类仅包含抽象方法,即 m1()、m2()、m3()。假设这个抽象类或接口将来不会改变。在这种情况下我应该选择什么以及为什么?他们中的任何一个会有更好的表现吗?

c# oop interface abstract

2
推荐指数
1
解决办法
4528
查看次数