簡體   English   中英

c# 編譯器如何處理這個 DateTime.ToOADate()?

[英]How does c# compiler treat this DateTime.ToOADate()?

我需要對大型數據集進行非常高性能的循環。 我需要比較時間戳,但我的日期是 OA 格式:

if (md.DT_OA > new DateTime(2011, 3, 13).ToOADate()) 

編譯器會在每個循環周期中評估new DateTime(2011, 3, 13).ToOADate()嗎? 或者“優化器”會在一開始就解決這個問題。

即我可以擺脫懶惰並在代碼中使用它嗎?

如您所知-我對編譯器的工作原理知之甚少...

編輯 1

評論啟發我做一個適當的測試:

下面的選項 2 比選項 1 3% faster 。這並不令人驚訝 - 編譯器似乎非常聰明或日期創建速度很快。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Test1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Go();
        }

        public static void Go() 
        {
            int c = 0;
            DateTime st = DateTime.Now;
            DateTime dt = new DateTime(2011, 3, 13);
            for (int i = 0; i < 1000000; i++) 
            {
                if (DateTime.Now > new DateTime(2011, 3, 13)) // Option 1
                //if (DateTime.Now > dt)                          // Option 2
                {
                    c++;
                }
            }

            MessageBox.Show("Time taken: " + DateTime.Now.Subtract(st).TotalMilliseconds + " c: " + c);
        } 
    }
}

我看不出它會優化它的理由......很肯定它不會(我知道它不會在 IL 層優化它,但這並沒有說明 JIT;但我真的不這么認為will -它不知道該方法每次都會返回相同的東西)。

相反,如果您關心它,請將其從循環中取出:

var oaDate = new DateTime(2011, 3, 13).ToOADate();
...loop...
    if (md.DT_OA > oaDate) {...}

Re just new DateTime(int,int,int) (comments); 讓我們創建一個測試程序:

    static void Main()
    {
        for (int i = 0; i < 1000; i++)
        {
            if (DateTime.Now > new DateTime(2011, 3, 13)) Console.WriteLine("abc");
        }
    }

如果我們編譯它然后反匯編 IL (reflector/ildasm/etc),我們得到:

L_0000: ldc.i4.0 
L_0001: stloc.0 
L_0002: br.s L_002b
L_0004: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
L_0009: ldc.i4 0x7db
L_000e: ldc.i4.3 
L_000f: ldc.i4.s 13
L_0011: newobj instance void [mscorlib]System.DateTime::.ctor(int32, int32, int32)
L_0016: call bool [mscorlib]System.DateTime::op_GreaterThan(valuetype [mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime)
L_001b: brfalse.s L_0027
L_001d: ldstr "abc"
L_0022: call void [mscorlib]System.Console::WriteLine(string)
L_0027: ldloc.0 
L_0028: ldc.i4.1 
L_0029: add 
L_002a: stloc.0 
L_002b: ldloc.0 
L_002c: ldc.i4 0x3e8
L_0031: blt.s L_0004
L_0033: ret 

查看 L_0009 到 L_0011 - 這是每次循環迭代創建new DateTimeL_0031: blt.s L_0004是循環重復)。 正如我所料,編譯器對您的要求非常直白。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM