系统 win11 22h2 22622.590
cpu i5-9600K
内存 32G
以下代码均不开优化,否则可能会被优化掉
场景 1 格式化为字符串
C# netcore 6.0.400
```
using System;
using System.Diagnostics;
var sw = Stopwatch.StartNew();
for (var i = 0; i < 1_000_000; i++)
{
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//var now = DateTime.Now;
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
```
Java 1.8.0.333
```
package com.company;
import
java.util.Date;
import java.text.SimpleDateFormat;
class Playground {
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long stime = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
Date now = new Date();
String nowString = format.format(now);
}
long etime = System.currentTimeMillis();
System.out.printf("%d ", (etime - stime));
}
}
```
以上代码分别执行 5 次
C# 243 232 237 233 236
Java 617 629 619 632 616
场景 1 只读取当前时间,不做格式化
C# netcore 6.0.400
```
using System;
using System.Diagnostics;
var sw = Stopwatch.StartNew();
for (var i = 0; i < 1_000_000; i++)
{
//var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var now = DateTime.Now;
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
```
Java 1.8.0.333
```
package com.company;
import
java.util.Date;
import java.text.SimpleDateFormat;
class Playground {
public static void main(String[] args) {
//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long stime = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
Date now = new Date();
//String nowString = format.format(now);
}
long etime = System.currentTimeMillis();
System.out.printf("%d ", (etime - stime));
}
}
```
以上代码分别执行 5 次
C# 39 38 39 39 39
Java 9 10 10 9 9
结论
1. 均执行时间字符串格式化时,C#比 Java 快
2. 仅执行获取当前时间的代码时,java 更快
关于结论 2 的分析
通过查看源代码,java 的 new Date() 仅执行一个成员赋值
```
public Date() {
this(System.currentTimeMillis());
}
public Date(long date) {
fastTime = date;
}
private transient long fastTime;
```
而 C#的 Date.Now 源码
```
public static DateTime Now
{
get
{
DateTime utc = UtcNow;
long offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out bool isAmbiguousLocalDst).Ticks;
long tick = utc.Ticks + offset;
if ((ulong)tick <= MaxTicks)
{
if (!isAmbiguousLocalDst)
{
return new DateTime((ulong)tick | KindLocal);
}
return new DateTime((ulong)tick | KindLocalAmbiguousDst);
}
return new DateTime(tick < 0 ? KindLocal : MaxTicks | KindLocal);
}
}
public static unsafe DateTime UtcNow
{
get
{
ulong fileTimeTmp; // mark only the temp local as address-taken
s_pfnGetSystemTimeAsFileTime(&fileTimeTmp);
ulong fileTime = fileTimeTmp;
if (s_systemSupportsLeapSeconds)
{
// Query the leap second cache first, which avoids expensive calls to GetFileTimeAsSystemTime.
LeapSecondCache cacheValue = s_leapSecondCache;
ulong ticksSinceStartOfCacheValidityWindow = fileTime - cacheValue.OSFileTimeTicksAtStartOfValidityWindow;
if (ticksSinceStartOfCacheValidityWindow < LeapSecondCache.ValidityPeriodInTicks)
{
return new DateTime(dateData: cacheValue.DotnetDateDataAtStartOfValidityWindow + ticksSinceStartOfCacheValidityWindow);
}
return UpdateLeapSecondCacheAndReturnUtcNow(); // couldn't use the cache, go down the slow path
}
else
{
return new DateTime(dateData: fileTime + (FileTimeOffset | KindUtc));
}
}
}
```
可以看出 java 的实现在仅 new Date()的情况下,执行的操作比 C#少很多,诸如 getTime 等都是调用时才计算,而 C#这边则是已经需要计算很多成员所以更慢.