Span<T> 范围运算符没有意义
Span<T> range operator doesn't make sense
我一辈子都无法理解 Span 的范围运算符背后的逻辑。
我有一个包含 IP 协议的以下字节数组 header:
---------------------------------------------------------------------------------
| | | | | | | | | | | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 9 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---------------------------------------------------------------------------------
| other data | src ip | dest ip |
---------------------------------------------------------------------------------
使用范围运算符,我需要使用以下值来提取正确的 4 字节数组:
Span<byte> ipHeader = ethernetFrame.IPHeader;
byte[] sourceIpAddress = ipHeader[12..16].ToArray();
byte[] destinationIpAddress = ipHeader[16..20].ToArray();
如果相反,我使用 Slice 方法,我最终得到:
Span<byte> ipHeader = ethernetFrame.IPHeader;
byte[] sourceIpAddress = ipHeader.Slice(12, 4).ToArray();
byte[] destinationIpAddress = ipHeader.Slice(16, 4).ToArray();
要求我给出比实际结束索引值大 1 的结束值的范围运算符背后的逻辑是什么?
从性能的角度来看我也很好奇(因为这个特定的代码块每分钟运行数百万次),无论如何使用 Slice 会更有效吗?
I cannot for the life of me understand the logic behind the Range operator of a Span.
值得注意的是,这并非特定于 Span - C# 中的范围总是 预期具有独占上限。 (有关更多信息,请参阅 tutorial。)
What is the logic behind the range operator that requires me to give an end value that's 1 past the actual ending index value?
只是一个独占上限。上限通常是排他的,这有很多好处。例如,请注意您的图片中有两个 |
分隔线?它们位于索引 12 和 16 - 这是之前范围的上限和之后范围的下限。相同的数字在两个地方都有用,所以你不需要开始加一或减一。
请注意,独占上限在 for
循环中也很常见。如果您想手动复制该 src IP 地址,我怀疑您会做类似的事情:
for (int index = 12; index < 16; index++)
{
// Copy item at index
}
我认为这比使用 包含 上限更符合习惯:
for (int index = 12; index <= 15; index++)
{
// Copy item at index
}
它也自然适用于指定为开始和长度的范围:
for (int index = start; index < start + length; index++)
{
// Copy item at index
}
(或者相反,使用独占上限,您只需从末尾减去开头即可找到长度,无需任何“加一”部分。)
I'm also curious from a performance perspective (because this particular code block runs millions of times per minute), would using Slice be more efficient anyway?
范围运算符已经对跨度进行了切片。构建新的字节数组可能效率低下 - 如果您可以避免这种情况并直接使用跨度,那将会更有效率。
一个有趣的 link 设计决策(包含与排除)可以找到 here。
报告中的结论是:
- 它允许 a.Length 作为没有 adding/subtracting 的端点 1.
- 它让一个范围的结尾成为下一个范围的开头而不重叠
- 它避免了 x..x-1
形式的难看的空范围
我一辈子都无法理解 Span 的范围运算符背后的逻辑。
我有一个包含 IP 协议的以下字节数组 header:
---------------------------------------------------------------------------------
| | | | | | | | | | | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 9 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---------------------------------------------------------------------------------
| other data | src ip | dest ip |
---------------------------------------------------------------------------------
使用范围运算符,我需要使用以下值来提取正确的 4 字节数组:
Span<byte> ipHeader = ethernetFrame.IPHeader;
byte[] sourceIpAddress = ipHeader[12..16].ToArray();
byte[] destinationIpAddress = ipHeader[16..20].ToArray();
如果相反,我使用 Slice 方法,我最终得到:
Span<byte> ipHeader = ethernetFrame.IPHeader;
byte[] sourceIpAddress = ipHeader.Slice(12, 4).ToArray();
byte[] destinationIpAddress = ipHeader.Slice(16, 4).ToArray();
要求我给出比实际结束索引值大 1 的结束值的范围运算符背后的逻辑是什么?
从性能的角度来看我也很好奇(因为这个特定的代码块每分钟运行数百万次),无论如何使用 Slice 会更有效吗?
I cannot for the life of me understand the logic behind the Range operator of a Span.
值得注意的是,这并非特定于 Span - C# 中的范围总是 预期具有独占上限。 (有关更多信息,请参阅 tutorial。)
What is the logic behind the range operator that requires me to give an end value that's 1 past the actual ending index value?
只是一个独占上限。上限通常是排他的,这有很多好处。例如,请注意您的图片中有两个 |
分隔线?它们位于索引 12 和 16 - 这是之前范围的上限和之后范围的下限。相同的数字在两个地方都有用,所以你不需要开始加一或减一。
请注意,独占上限在 for
循环中也很常见。如果您想手动复制该 src IP 地址,我怀疑您会做类似的事情:
for (int index = 12; index < 16; index++)
{
// Copy item at index
}
我认为这比使用 包含 上限更符合习惯:
for (int index = 12; index <= 15; index++)
{
// Copy item at index
}
它也自然适用于指定为开始和长度的范围:
for (int index = start; index < start + length; index++)
{
// Copy item at index
}
(或者相反,使用独占上限,您只需从末尾减去开头即可找到长度,无需任何“加一”部分。)
I'm also curious from a performance perspective (because this particular code block runs millions of times per minute), would using Slice be more efficient anyway?
范围运算符已经对跨度进行了切片。构建新的字节数组可能效率低下 - 如果您可以避免这种情况并直接使用跨度,那将会更有效率。
一个有趣的 link 设计决策(包含与排除)可以找到 here。
报告中的结论是:
- 它允许 a.Length 作为没有 adding/subtracting 的端点 1.
- 它让一个范围的结尾成为下一个范围的开头而不重叠
- 它避免了 x..x-1 形式的难看的空范围