小编Yus*_*tak的帖子

C# 到 CIL 拳击 vs. ToString 成本

我正在通过 C#(第 4 版)阅读 CLR 一书,不是作为 C# 的新手,而是作为了解该语言的人,试图提高我对 CLR 底层功能的掌握程度。

无论如何,在这本书中给出了一个例子 (pg127-131),当讨论值类型的装箱/拆箱时,它以调用 Console.WriteLine 结束,值类型被连接到作为参数传递的字符串。

这本书解释了装箱和拆箱/复制操作会导致开销,这是我已经知道的,但随后说明可以通过在传入的值类型上运行 .ToString() 来优化示例。

我创建了一个示例程序并编译它,然后使用 ILDASM 来检查它生成的 IL。带有 ToString 的版本本质上是相同的,但用对 ToString 的“调用”替换了“box”指令(没有震惊)。

我在 100000 次运行的循环中对代码进行了基准测试,并且没有区别(它波动哪个更快)。我意识到在进行基准测试(缓存等)时其他因素会起作用,但通过本书解释它的方式,我曾期望即使在幼稚的基准测试中避免“box”指令时也会看到显着差异。

难道只是调用一个函数并没有好多少?是否在 ToString 中进行了拳击操作,使好处无效并且这本书是错误的?有人可以对此有所了解吗?

作为参考,这里有两个 ILDASM 读数:


.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       24 (0x18)
  .maxstack  2
  .locals init (int32 V_0)
  IL_0000:  ldc.i4.4
  IL_0001:  stloc.0
  IL_0002:  ldloc.0
  IL_0003:  box        [mscorlib]System.Int32
  IL_0008:  ldstr      "."
  IL_000d:  call       string [mscorlib]System.String::Concat(object,
                                                              object)
  IL_0012:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0017:  ret
} …
Run Code Online (Sandbox Code Playgroud)

c# performance boxing cil ildasm

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

为 IQueryable<T> 生成表达式

我正在使用 LINQ->WCF 数据服务->EF,它支持 LINQ 的一个子集,但有一些注意事项。我已经受够了,一旦学习各种事物的技巧和解决方法没有问题,但我想提出一个可重用的表达发电机仅比较Date的一部分DateTime

对于常规 EF,您可以使用EntityFunctions.TruncateTime(EF<6) 或DbFunctions.TruncateTime(EF6+),但这不适用于数据服务。

到目前为止,我的解决方案是反复构建混乱的 where 子句:

.Where(x => x.DateProperty.Year == DateToCompare.Year && 
            x.DateProperty.Month == DateToCompare.Month && 
            x.DateProperty.Day == DateToCompare.Day);
Run Code Online (Sandbox Code Playgroud)

不得不重复编写(但它有效)只是令人讨厌,所以我试图创建类似的东西:

.WhereDate(x => x.DateProperty, DateToCompare);
Run Code Online (Sandbox Code Playgroud)

任何类似的事情都可以,只是简短、甜蜜和可读——我讨厌重复的不必要的代码。

结构不是问题,我知道我需要一些需要IQueryable<T>Func<T, DateTime>(或Expression<Func<T, DateTime>>DateTime和返回的东西IQueryable<T>

public static IQueryable<T> WhereDate<T>(this IQueryable<T> data, Func<T, DateTime>> selector, DateTime date)
{
    return data.Where(/*Something*/);
};
Run Code Online (Sandbox Code Playgroud)

我遇到麻烦的地方是采取这一点并构建一个表达式,该表达式可以放入该 where 子句中,而不会违反表达式树的限制。我不完全确定如何获取现有查询并将我自己的 where 语句添加到表达式而不执行 a .Where,我认为这可能是这里的关键。我想我需要接受Expression<Func<T, DateTime>>并构建一些使用它来添加Expression<Func<T, bool>> to …

c# linq wcf datetime entity-framework

4
推荐指数
1
解决办法
2907
查看次数

包装System.Math是个坏主意吗?

我有自己的数学库,我希望它被称为"数学"(我一直称它为"数学").它位于自己的命名空间中,但类名为"Math"仍然与System.Math冲突.我解决这个问题的方法是在System.Math中为我的库添加一个包装器,它只显式调用System.Math函数,然后我必须添加

using Math = Yushatak.Libraries.Math;
Run Code Online (Sandbox Code Playgroud)

到每个使用Math.*功能的文件.我不觉得这是最好的方法,我也担心包装会造成额外的开销,而且这不是你想要开销的地方..

建议吗?有没有更好的方法来"扩展"System.Math?这只是一个坏主意,我应该回到"数学"?有什么建议吗?:P

包装方法示例:

    public static decimal Abs(decimal value)
    {
        return System.Math.Abs(value);
    }
Run Code Online (Sandbox Code Playgroud)

c# math

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

C#Enum.HasFlag与按位AND运算符检查

如果你有一个enum用于位标志,即,

[Flags]
internal enum _flagsEnum : byte
{
    None = 0,           //00000000
    Option1 = 1,        //00000001
    Option2 = 1 << 1,   //00000010
    Option3 = 1 << 2,   //00000100
    Option4 = 1 << 3,   //00001000
    Option5 = 1 << 4,   //00010000
    Option6 = 1 << 5,   //00100000
    Option7 = 1 << 6,   //01000000
    Option8 = 1 << 7,   //10000000
    All = Byte.MaxValue,//11111111
}

_flagsEnum myFlagsEnum = _flagsEnum.None;
Run Code Online (Sandbox Code Playgroud)

这样做更快..

bool hasFlag = myFlagsEnum.HasFlag(_flagsEnum.Option1);
Run Code Online (Sandbox Code Playgroud)

或者......

bool hasFlag = myFlagsEnum & _flagsEnum.Option1 …
Run Code Online (Sandbox Code Playgroud)

c# optimization performance enums bit-manipulation

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