C# DateTime.AddDays或新的DateTime
我正在创建一个月的约会清单。我想知道什么会更有效率C# DateTime.AddDays或新的DateTime,c#,.net,performance,datetime,stopwatch,C#,.net,Performance,Datetime,Stopwatch,我正在创建一个月的约会清单。我想知道什么会更有效率 List<DateTime> GetDates(DateTime StartDay) { List<DateTime> dates = new List<DateTime>(); int TotalDays=StartDay.AddMonths(1).AddDays(-1).Day; for (int i=1; i<TotalDays; i++) { dates.Add(new Da
List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
int TotalDays=StartDay.AddMonths(1).AddDays(-1).Day;
for (int i=1; i<TotalDays; i++) {
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i));
}
return dates;
}
或
基本上,new DateTime或DateTime.addDays更有效吗
更新:
static void Main(string[] args) {
System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();
long t1, t2, total;
List<DateTime> l;
DateTime begin = DateTime.Now;
total = 0L;
for (int i=0; i<10; i++) {
sw.Start();
l = GetDates(begin);
sw.Stop();
sw.Stop();
t1 = sw.ElapsedTicks;
sw.Reset();
sw.Start();
l = GetDates2(begin);
sw.Stop();
t2=sw.ElapsedTicks;
total += t1- t2;
Console.WriteLine("Test {0} : {1} {2} : {3}", i,t1,t2, t1- t2);
}
Console.WriteLine("Total: {0}", total);
Console.WriteLine("\n\nDone");
Console.ReadLine();
}
static List<DateTime> GetDates(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
int TotalDays=StartDay.AddMonths(10000).AddDays(-1).Day;
for (int i=1; i<TotalDays; i++) {
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i));
}
return dates;
}
static List<DateTime> GetDates2(DateTime StartDay) {
List<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(10000);
for (DateTime curr=StartDay; !curr.Equals(NextMonth); curr=curr.AddDays(1)) {
dates.Add(curr);
}
return dates;
}
结果总是负面的。。。相反,看起来构造函数和整数测试是更有效的方法。测量它-编写一个测试程序,看看哪一个需要更少的时间。我相信datetime操作返回新的datetime结构,因此您将以任何方式创建新实例
因为他们最终都做了相同的事情,所以没有太大区别
如果你想提高效率,就用记号吧。我在DateTime中看到的所有调用最终都会在完成任何计算之前转换为滴答声。除非您正在进行一些财务处理,否则我更担心的是可读性而不是性能。只有在这里这样的地方开始担心性能,如果它已经被证明是一个瓶颈。我同意Mark的观点。自己测试这两种方法,看看哪一种更快。使用Stopwatch类可以获得每个方法运行所需时间的精确计时。我的第一个猜测是,既然两者最终都创造了新的结构,那么任何速度差都可以忽略不计。另外,由于最多只能生成一个月的31天的日期,我认为这两种方法都不会比另一种慢很多。可能是你生成了数千或数百万个日期,这会产生影响,但对于31个日期,这可能是过早的优化。很难想象这会产生显著影响,但Reflector表明AddDays技术应该更有效 比较AddDays与AddDouble、Int32的核心逻辑 AddDays只是将指定的天数转换为相当于长时间的刻度数,并将其添加到现有的刻度中 使用年/月/日构造函数创建新的DateTime需要更多的计算。构造器必须检查指定的年份是否是闰年,在每个月分配一个天数数组,执行一系列额外的操作,最终得到这三个数字所代表的刻度数
编辑:DateTime.AddDaysint比新的DateTimeint,int,int快,但是第一个算法比第二个算法快。这可能是因为第二种算法的迭代成本要高得多。正如您在编辑中所观察到的,这很可能是因为DateTime.Equals比比较整数更昂贵。这是一个正在运行的测试程序,实现了一些算法,以便能够对它们进行实际比较,但它们仍然需要工作:
class Program
{
static void Main(string[] args)
{
IList<DateTime> l1, l2;
DateTime begin = new DateTime(2000, 1, 1);
Stopwatch timer1 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l1 = GetDates(begin);
timer1.Stop();
Stopwatch timer2 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l2 = GetDates2(begin);
timer2.Stop();
Console.WriteLine("new DateTime: {0}\n.AddDays: {1}",
timer1.ElapsedTicks, timer2.ElapsedTicks);
Console.ReadLine();
}
static IList<DateTime> GetDates(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
int TotalDays = DateTime.DaysInMonth(StartDay.Year, StartDay.Month);
for (int i = 0; i < TotalDays; i++)
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i + 1));
return dates;
}
static IList<DateTime> GetDates2(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(1);
for (DateTime curr = StartDay; !curr.Equals(NextMonth); curr = curr.AddDays(1))
dates.Add(curr);
return dates;
}
} // class
输出I添加了逗号:
new DateTime: 545,307,375
.AddDays: 180,071,512
这些结果对我来说似乎很清楚,但老实说,我认为它们会更接近。请注意:第一个代码示例不起作用-DateTime.Day返回月份的日期。如果你想要这个数量,可以使用时间跨度。好的,那么,对于2009年1月1日,它会加上一个月2009年2月1日,减去一天2009年1月31日,然后给我我我想要的第31天部分。从上下文来看,StartDay不能假设从月的第一天开始。如果我从本月5号开始,我会在4号结束使用该代码。如果您总是在月边界上,我建议使用DateTime.DaysInMonth静态函数。啊,现在就知道了-如果您修改第二个测试,使其与第一个测试完全相同,但替换日期。Addnew DateTimeStartDay.Year,StartDay.month,I with dates.AddStartDay.AddDays1,第二个版本的执行速度大约是第一个版本的两倍。第一次测试运行将比任何后续运行都慢,无论您使用哪种算法。您应该真正使用System.Diagnostics.Stopwatch进行计时。在此处报告您的结果:您相信吗?引用它不是更好吗?此方法不会更改此DateTime的值。相反,将返回一个新的DateTime,其值是此操作的结果。此外,尽管它们都创建了新的DateTime实例,但这两个构造函数涉及非常不同的算法。你批评我的措辞吗?我觉得我写它的方式和包含链接的方式更为礼貌。虽然它们都创建了新实例,但它们肯定不会做相同的事情。它们最终做了相同的事情,这两种方法之间的区别不大。别胡说八道,伙计。不仅如此,在分析第一行的时候,你完全忽略了第二行,这说明了一个事实,处理日期时间结构最有效的方法就是只使用滴答声。哎呀,我同意。我同意第二部分,我的愤怒已经激起。必须粉碎。+1,这绝对是最重要的建议。我对这件事深究了一下,觉得有点傻。D:
long num = (long) ((value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
if ((num <= -315537897600000L) || (num >= 0x11efae44cb400L)) {
// Throw omitted
}
return this.AddTicks(num * 0x2710L);
if (((year >= 1) && (year <= 0x270f)) && ((month >= 1) && (month <= 12)))
{
int[] numArray = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
if ((day >= 1) && (day <= (numArray[month] - numArray[month - 1])))
{
int num = year - 1;
int num2 = ((((((num * 0x16d) + (num / 4)) - (num / 100)) + (num / 400)) + numArray[month - 1]) + day) - 1;
return (num2 * 0xc92a69c000L);
}
}
// Throw omitted
class Program
{
static void Main(string[] args)
{
IList<DateTime> l1, l2;
DateTime begin = new DateTime(2000, 1, 1);
Stopwatch timer1 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l1 = GetDates(begin);
timer1.Stop();
Stopwatch timer2 = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
l2 = GetDates2(begin);
timer2.Stop();
Console.WriteLine("new DateTime: {0}\n.AddDays: {1}",
timer1.ElapsedTicks, timer2.ElapsedTicks);
Console.ReadLine();
}
static IList<DateTime> GetDates(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
int TotalDays = DateTime.DaysInMonth(StartDay.Year, StartDay.Month);
for (int i = 0; i < TotalDays; i++)
dates.Add(new DateTime(StartDay.Year, StartDay.Month, i + 1));
return dates;
}
static IList<DateTime> GetDates2(DateTime StartDay)
{
IList<DateTime> dates = new List<DateTime>();
DateTime NextMonth = StartDay.AddMonths(1);
for (DateTime curr = StartDay; !curr.Equals(NextMonth); curr = curr.AddDays(1))
dates.Add(curr);
return dates;
}
} // class
new DateTime: 545,307,375
.AddDays: 180,071,512