惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
N
Netflix TechBlog - Medium
腾讯CDC
C
Check Point Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
S
SegmentFault 最新的问题
F
Fortinet All Blogs
美团技术团队
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
F
Full Disclosure
Recorded Future
Recorded Future
D
DataBreaches.Net
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
J
Java Code Geeks
I
InfoQ
Y
Y Combinator Blog
A
About on SuperTechFans
AI
AI
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
W
WeLiveSecurity
M
MIT News - Artificial intelligence
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Schneier on Security
Schneier on Security
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
V2EX - 技术
V2EX - 技术
Project Zero
Project Zero

博客园 - ProjectDD

NET 中 Async/Await 的演进:从状态机到运行时优化的 Continuation C# 指针用法小结 C# BinaryPrimitives 类 C# 内存对齐 linq 查询关于 from子句 关于C# await的一点新理解 关于排序算法 C# Dev Kit 经常导致崩溃 span,memory,ArrayPool,MemoryPool,等的性能对比 C# simd 性能雷点记录 C# 模式匹配里应该注意的几点 高中生理解梯度为何是方向导数极大值 概略 deep net 通过relu 进行函数逼近 win10 下安装 rust 的 依赖配置,通过vs2022 C# 有多需要aot 24个希腊字母的中文拼音版 英语发音探讨 sagemath 9.x 下的 jupyter 工作路径设置 Serializing delegates is not supported on this platform
不太会用Span<T> 看文档上的优点估摸着试试
ProjectDD · 2023-11-04 · via 博客园 - ProjectDD

本次采用最流行而又权威的benchmarkdotnet 基准测试库进行

因为确实看文档和网文上关于Span<T>的示例很少,最多就是切string, substring split方面的,具体意思感觉就是多次被调用时如果都在创建临时的数组对象会给gc带来负荷,而这正是Span<T>能解决的

目前我对Span<T>的理解是 在栈上的一块连续内存的安全抽象,当初始化的传入的 数组对象可以看成是该数组对象的一个引用别名。

下面是测试代码:

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Tester;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;

[SimpleJob(iterationCount: 100)]
public class Test {
  [Params(20)]
  public int len;
  public int[] source;
  [GlobalSetup]
  public void Setup() {
    source = new int[len];
    for (var i = 0; i < len; i++) {
      source[i] = i;
    }
  }
  [Benchmark]
  public int[] GetOddByGeneral() {
    var result = new int[len];
    int _len = 0;
    for (var i = 0; i < len; i++) {
      if (source[i] % 2 == 1) {
        result[i] = source[i];
        _len++;
      }
    }
    return result[0.._len];
  }
  [Benchmark]
  public int[] GetOddBySpan() {
    Span<int> sourceSpan = stackalloc int[len];
    int _len = 0;
    for (var i = 0; i < len; i++) {
      if (source[i] % 2 == 1) {
        sourceSpan[i] = source[i];
        _len++;
      }
    }
    return sourceSpan.Slice(0, _len).ToArray();
  }

}


public class Program {
  static void Main(string[] args) {
    var summary = BenchmarkDotNet.Running.BenchmarkRunner.Run<Test>(
      BenchmarkDotNet.Configs.DefaultConfig.Instance
      .WithSummaryStyle(BenchmarkDotNet.Reports.SummaryStyle.Default.WithMaxParameterColumnWidth(100))
    );
    Console.WriteLine(summary);
  }
}

//结果截图

我不知道我设计这个测试逻辑是否合理,就从测试结果看确实 Span<T>有一点微弱的优势,可能是我代码逻辑不合理造成的,因为在general中我有多余的切片操作这其实是额外的应该避免的。

不过Span<T>方法里也有 slice 先算它们扯平。

 在general方法中 每被调一次就会多一次创建数组的开销 逻辑上说会增加内存消耗,但具体什么情况我不知道。