在.Net 7源码中bool代码优化

开发 前端
代码总是从简单到复杂,从易读到晦涩,有的是业务逻辑复杂导致代码也复杂,有的是为了性能优化,导致代码不那么易读易懂了.这里主要是看到最近.Net bool类型源码变化。

起因

代码总是从简单到复杂,从易读到晦涩,有的是业务逻辑复杂导致代码也复杂,有的是为了性能优化,导致代码不那么易读易懂了.这里主要是看到最近.Net bool类型源码变化.

  • Streamline bool.TryParse/Format (#64782)
  • Fix bool.TryParse/Format on big-endian systems (#65078)

在.Net 6中TryParse

public static bool TryParse(ReadOnlySpan<char> value, out bool result)
{
if (IsTrueStringIgnoreCase(value)) //关注IsTrueStringIgnoreCase
{
result = true;
return true;
}
if (IsFalseStringIgnoreCase(value)) //关注和IsFalseStringIgnoreCase
{
result = false;
return true;
}
value = TrimWhiteSpaceAndNull(value);
if (IsTrueStringIgnoreCase(value))
{
result = true;
return true;
}
if (IsFalseStringIgnoreCase(value))
{
result = false;
return true;
}
result = false;
return false;
}

在TryParse中,调用IsTrueStringIgnoreCase和IsFalseStringIgnoreCase这两个函数这时候是易读易懂.

在.Net 7中TryParse(优化)

//只保留IsTrueStringIgnoreCase和IsFalseStringIgnoreCase
internal static bool IsTrueStringIgnoreCase(ReadOnlySpan<char> value)
{
// "true" as a ulong, each char |'d with 0x0020 for case-insensitivity
// 先判断cpu支持大小端模式, 采用无符号long类型存储4个字符的ASCII码值 小端:: 65→e 75→u 72→r 74→t
// 将value转为byte数组,读取为ulong类型,然后或运算, 0x20为十六进制 是十进制32 或运算:: A | 32 = a 这样就不用区分大小写
// 0x0020002000200020为4个0x20,因为值一样,不区分大小端
ulong true_val = BitConverter.IsLittleEndian ? 0x65007500720074ul : 0x74007200750065ul;
return value.Length == 4 &&
(MemoryMarshal.Read<ulong>(MemoryMarshal.AsBytes(value)) | 0x0020002000200020) == true_val;
}

internal static bool IsFalseStringIgnoreCase(ReadOnlySpan<char> value)
{
// "fals" as a ulong, each char |'d with 0x0020 for case-insensitivity
// ulong类型只能存4个字符,所以存储 "fals"这4个字符 73→s 6c→l 61→a 66→f
// 最后1个字符进行与0x20进行或运算,得到小写字符和'e'进行判断
ulong fals_val = BitConverter.IsLittleEndian ? 0x73006C00610066ul : 0x660061006C0073ul;
return value.Length == 5 &&
(((MemoryMarshal.Read<ulong>(MemoryMarshal.AsBytes(value)) | 0x0020002000200020) == fals_val) &
((value[4] | 0x20) == 'e'));
}

在.Net 6中TryFormat

public bool TryFormat(Span<char> destination, out int charsWritten)
{
if (m_value) //为真
{
if ((uint)destination.Length > 3u)
{
//进行4次赋值操作
destination[0] = 'T';
destination[1] = 'r';
destination[2] = 'u';
destination[3] = 'e';
charsWritten = 4;
return true;
}
}
else if ((uint)destination.Length > 4u) //不为真
{
//进行5次赋值操作
destination[0] = 'F';
destination[1] = 'a';
destination[2] = 'l';
destination[3] = 's';
destination[4] = 'e';
charsWritten = 5;
return true;
}
charsWritten = 0;
return false;
}

在.Net 7中TryFormat(优化)

public bool TryFormat(Span<char> destination, out int charsWritten)
{
if (m_value)
{
if ((uint)destination.Length > 3) // uint cast, per https://github.com/dotnet/runtime/issues/10596
{
//先判断cpu支持大小端模式, 采用无符号long类型存储4个字符的ASCII码值 小端:: 65→e 75→u 72→r 74→t
//将Span<char>转为byte数组,将true_val写入,减少赋值的次数,与.Net 6中4次赋值操作,这里只有1次
ulong true_val = BitConverter.IsLittleEndian ? 0x65007500720054ul : 0x54007200750065ul; // "True"
MemoryMarshal.Write<ulong>(MemoryMarshal.AsBytes(destination), ref true_val);
charsWritten = 4;
return true;
}
}
else
{
if ((uint)destination.Length > 4)
{
//不为真时,进行2次赋值操作 第1次 ulong 只能存4个字符, 第2次通过下标赋值为'e'
ulong fals_val = BitConverter.IsLittleEndian ? 0x73006C00610046ul : 0x460061006C0073ul; // "Fals"
MemoryMarshal.Write<ulong>(MemoryMarshal.AsBytes(destination), ref fals_val);
destination[4] = 'e';
charsWritten = 5;
return true;
}
}

charsWritten = 0;
return false;
}

在.Net 7中对bool的改进,就是减少赋值操作,将4个字符转为ulong,实现了一次将4个字符赋值.还有通过位或操作巧妙的实现将大写字母进行转换.这种实现不是第一次看到,曾在wrk(压力工具,使用c语言编写)看到:

#define LOWER(c)     (unsigned char)(c | 0x20)
责任编辑:未丽燕 来源: 今日头条
相关推荐

2009-08-04 17:16:16

ASP.NET代码优化

2009-09-03 09:57:59

Visual StudVS 2010

2024-03-11 08:11:27

Node.js.NET低代码平台

2009-07-30 18:45:05

ASP.NET中防止页

2009-02-27 16:22:34

AjaxProAjax.NET

2022-12-08 08:00:00

.NET 7BitArray数据执行

2011-09-19 16:38:32

windowsXPvista

2009-08-19 09:28:42

Windows 7Telnet服务

2012-12-24 09:23:27

ASP.NETC#IIS

2009-08-10 09:19:47

.NET反应性框架

2009-07-17 13:46:52

.Net Micro

2009-07-17 13:56:44

.Net Micro

2023-04-25 08:01:23

JavaQuarkusKubernetes

2021-04-29 08:11:11

SQL优化作用

2009-07-29 15:51:29

ASP.NET中执行w

2011-03-24 09:23:43

.NET 4多核并行

2011-08-31 17:58:00

VS.netLUA开发环境

2009-07-23 16:44:51

AdRotator控件ASP.NET

2021-09-11 22:32:26

Go 绑定 Host

2009-01-16 13:17:16

AjaxASP.NET.NET
点赞
收藏

51CTO技术栈公众号