4

.net core 的时间日期类为啥这么慢, 跟 Java 至少几十倍的差距

 2 years ago
source link: https://www.v2ex.com/t/877417
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

.net core 的时间日期类为啥这么慢, 跟 Java 至少几十倍的差距

thinkershare      9 小时 41 分钟前   4

不知道你在说啥, 你这样提问, 不提供代码, 没有任何意义. .NET 日志库一大堆, 我完全不相信你自己写的日志组件能达到第三方日志组件的水平, 因为你一看对.NET 常规 API 都不熟练.

chouchoui      9 小时 26 分钟前 via iPhone   8

基于.net 没啥好用的日志组件, 就自己写了》谢谢 Java boy 今天创造的笑话。

Leviathann      9 小时 22 分钟前 via iPhone

为什么要用一个被官方标记 deprecated 的类我说的是 date

thinkershare      9 小时 3 分钟前   1

https://imgur.com/QUQOi6q.jpg ,Java 提供的 Date 类型早就被废弃, 和 DateTime 提供的 API 都没法公平比较. 根本就不应该被使用. .NET 提供的 DateTime 其实也应该被废弃, 使用 DateTimeOffset 替代.

Bingchunmoli      8 小时 54 分钟前 via Android

@thinkershare 实际是项目依旧 1.8 ,有些序列化支持 D'ateTime 还需要额外操作,date 实际代码用的还是更多。 还是早点更替把,框架支持跟上

Maboroshii      8 小时 17 分钟前 via Android

.net 性能确实不咋地… 但是最近也需要用.net 开发。搭车请教一下.net6 怎么用 github 上别人写的库?我拉下来发现.net 版本不一致都不能跑… 是一个一个文件复制到我自己的项目里面用吗

a33291      8 小时 15 分钟前

系统 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#这边则是已经需要计算很多成员所以更慢.

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK