开发者

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

I need to have very high-performance loop going over large datasets. I need to compare TimeStamps, but my dates are in OA format:

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

Will the compiler evaluate new DateTime(2011, 3, 13).ToOADate() in each loop cycle? Or will the "optimiser" work this out once at beginning.

i.e Can I get away with being lazy and having this in the code?

As you can tell - I don't know much about how compiler works...

EDIT 1

Comments inspired me do do a proper test:

Option 2 below is about 3% faster than Option 1. Which is surprising not MUCH faster - the compiler seems to be very smart or date creation is fast.

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 : For开发者_高级运维m
    {
        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);
        } 
    }
}


I see no reason it would optimize that... pretty sure it won't (I know it won't optimize it at the IL layer, but that doesn't say anything about the JIT; but I really don't think it will - it doesn't know that the method is always going to return the same thing each time).

Instead, lift it out of the loop if you care about it:

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

Re just new DateTime(int,int,int) (comments); let's create a test program:

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

if we compile that and then disassemble the IL (reflector/ildasm/etc), we get:

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 

Look at L_0009 thru L_0011 - that is creating the new DateTime per loop iteration (L_0031: blt.s L_0004 is the loop repeat). The compiler has been very literal with your request, as I would expect.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜