C#高性能开发之类型系统:从C# 7.0 到C# 14的类型系统演进全景
自C# 7.0以来,C#语言在类型系统方面引入了众多新数据类型、类型构造和语言特性,以提升性能、类型安全性和开发效率。本文全面整理了从C# 7.0到C# 14.0(截至2025年4月,C# 14.0为预览版)类型系统的新增内容,包括值元组、Span<T>
、ReadOnlySpan<T>
、Memory<T>
、ReadOnlyMemory<T>
、可空引用类型、记录、本机大小整数、记录结构、内联数组,以及其他增强(如只读结构、泛型数学支持)。
版本概览
以下是C# 7.0至C# 14.0中类型系统新增或增强的主要内容:
C# 版本 | 新增/增强内容 | 发布年份 | 描述 |
---|---|---|---|
7.0 | 值元组(Value Tuples) | 2017 | 轻量级数据结构,支持多值返回和解构 |
7.2 | Span, ReadOnlySpan, 只读结构, 引用结构 | 2017 | 高性能内存操作和不可变/栈分配结构体 |
8.0 | 可空引用类型, Memory, ReadOnlyMemory | 2019 | 空值安全性和托管内存块 |
9.0 | 记录, 本机大小整数, 初始化器专用类型 | 2020 | 值语义引用类型、本机整数和不可变属性 |
10.0 | 记录结构, 全局 using 指令 | 2021 | 值类型记录和简化类型引用 |
11.0 | 必需成员, 泛型数学支持, 文件局部类型 | 2022 | 强制初始化、泛型运算和类型作用域限制 |
12.0 | 内联数组 | 2023 | 固定大小数组结构,优化性能 |
13.0 | 参数集合扩展, 引用结构接口支持, 部分属性 | 2024 | 扩展params、ref struct接口和部分属性定义 |
14.0 | field 关键字, 隐式 span 转换, nameof 增强, lambda 参数修饰符, partial 成员扩展, 空条件赋值 |
2025 | 增强属性访问、span 使用、泛型处理、lambda 表达、partial 类型和空值处理 |
以下按版本逐一详述,每节包含特性表格、代码示例和分析。
C# 7.0:值元组
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
值元组 (Value Tuples) | 轻量级值类型,支持多值返回、命名元素和解构 | 方法返回多个值、临时数据分组 | 值类型,栈分配;.NET Framework需引用System.ValueTuple包 |
概述
值元组基于System.ValueTuple
,允许方法返回多个值,支持命名元素和解构,简化数据传递。
语法
声明: (type1, type2, ...) tupleName = (value1, value2, ...);
命名元素: (type1 name1, type2 name2, ...) tupleName = (value1, value2, ...);
解构: var (var1, var2, ...) = tupleName;
示例代码
public (int id, string name) GetPerson()
{
return (1, "Alice");
}
var person = GetPerson();
Console.WriteLine($"ID: {person.id}, Name: {person.name}");
// 解构
var (id, name) = GetPerson();
Console.WriteLine($"ID: {id}, Name: {name}");
适用场景
方法返回多个相关值。 临时数据分组,无需定义类或结构。 解构赋值,简化代码。
注意事项
值类型,适合轻量数据。 .NET Framework项目需引用System.ValueTuple NuGet包。
C# 7.2:Span, ReadOnlySpan, 只读结构, 引用结构
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
Span | 表示连续内存块的引用,支持读写 | 高性能数组/内存操作 | ref struct,栈分配,生命周期限制 |
ReadOnlySpan | 只读连续内存块引用 | 高性能只读操作 | 同上,需确保内存边界安全 |
只读结构 (readonly struct) | 不可变结构体,优化性能 | 不可变数据结构 | 所有实例字段必须只读 |
引用结构 (ref struct) | 栈分配结构体 | 高性能内存管理 | 不可boxing或作为接口实现 |
概述
Span<T>
和ReadOnlySpan<T>
是高性能值类型,表示连续内存块引用,适合数组和本机内存操作。readonly struct
确保结构体不可变,ref struct
限制为栈分配,支持Span<T>
等类型。
语法
Span: Span<T> span = collection.AsSpan();
ReadOnlySpan: ReadOnlySpan<T> readOnlySpan = collection.AsSpan();
只读结构: readonly struct StructName { ... }
引用结构: ref struct StructName { ... }
示例代码
// Span<T> 和 ReadOnlySpan<T>
int[] numbers = [1, 2, 3, 4, 5];
Span<int> span = numbers.AsSpan(1, 3);
span[0] = 10;
Console.WriteLine(string.Join(", ", span.ToArray())); // 10, 3, 4
ReadOnlySpan<char> text = "Hello".AsSpan();
Console.WriteLine(text.Slice(0, 2).ToString()); // He
// 只读结构
readonly struct Point
{
public int X { get; init; }
public int Y { get; init; }
}
Point point = new() { X = 1, Y = 2 };
Console.WriteLine($"({point.X}, {point.Y})"); // (1, 2)
// 引用结构
ref struct Buffer
{
public Span<int> Data;
public Buffer(Span<int> data) => Data = data;
}
Buffer buffer = new(numbers.AsSpan());
buffer.Data[0] = 10;
Console.WriteLine(numbers[0]); // 10
适用场景
高性能字符串解析、缓冲区处理。 不可变数据结构(只读结构)。 避免堆分配(引用结构)。
注意事项
Span<T>
和ReadOnlySpan<T>
不可用于异步方法。ref struct
限制严格,需管理生命周期。
C# 8.0:可空引用类型, Memory, ReadOnlyMemory
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
可空引用类型 | 引用类型可标记为可空,默认非null | 增强空值安全性 | 需启用可空上下文,处理编译器警告 |
Memory | 托管内存块,支持读写 | 异步和高性能内存操作 | 适合异步场景,需管理生命周期 |
ReadOnlyMemory | 只读托管内存块 | 只读异步内存操作 | 同上 |
概述
可空引用类型通过?
后缀指定引用类型是否可为null,减少空引用异常。Memory<T>
和ReadOnlyMemory<T>
表示托管内存块,支持异步场景。
语法
可空引用类型: string? nullable; string nonNullable;
Memory: Memory<T> memory = collection.AsMemory();
ReadOnlyMemory: ReadOnlyMemory<T> readOnlyMemory = collection.AsMemory();
示例代码
// 可空引用类型
#nullable enable
string nonNullable = "Hello";
string? nullable = null;
if (nullable != null)
{
Console.WriteLine(nullable.Length);
}
// Memory<T> 和 ReadOnlyMemory<T>
int[] numbers = [1, 2, 3, 4, 5];
Memory<int> memory = numbers.AsMemory(1, 3);
Span<int> span = memory.Span;
span[0] = 10;
Console.WriteLine(string.Join(", ", memory.ToArray())); // 10, 3, 4
ReadOnlyMemory<char> text = "Hello".AsMemory();
Console.WriteLine(text.Slice(0, 2).Span.ToString()); // He
适用场景
增强空值安全性(可空引用类型)。 异步内存操作(Memory)。 只读数据传递(ReadOnlyMemory)。
注意事项
可空引用类型需显式启用。 Memory生命周期需管理。
C# 9.0:记录, 本机大小整数, 初始化器专用类型
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
记录 (Records) | 具有值语义的引用类型,默认不可变 | 数据建模,值相等性 | 默认不可变,可添加可变行为 |
本机大小整数 (nint, nuint) | 本机大小整数,映射IntPtr/UIntPtr | 本机代码互操作 | 平台依赖,需考虑兼容性 |
初始化器专用类型 (init-only setters) | 初始化后不可变属性 | 不可变数据模型 | 仅初始化时可赋值 |
概述
记录是具有值语义的引用类型,自动实现相等性。nint
和nuint
支持本机大小整数。init
修饰符增强属性不可变性。
语法
记录: public record ClassName(type1 Property1, ...);
本机大小整数: nint nativeInt; nuint nativeUInt;
init-only: public type Property { get; init; }
示例代码
// 记录
public record Person(string FirstName, string LastName);
var person1 = new Person("Alice", "Smith");
var person2 = new Person("Alice", "Smith");
Console.WriteLine(person1 == person2); // True
var person3 = person1 with { LastName = "Johnson" };
Console.WriteLine(person3); // Person { FirstName = Alice, LastName = Johnson }
// 本机大小整数
nint nativeInt = 42;
nuint nativeUInt = 42u;
Console.WriteLine($"Native int: {nativeInt}, Native uint: {nativeUInt}");
// 初始化器专用类型
public class Student
{
public string Name { get; init; }
}
var student = new Student { Name = "Alice" };
Console.WriteLine(student.Name); // Alice
适用场景
数据传输对象(记录)。 本机代码互操作(nint, nuint)。 不可变数据模型(init-only)。
注意事项
记录支持继承,需保持值语义。 本机大小整数平台依赖。
C# 10.0:记录结构, 全局 using 指令
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
记录结构 (Record Structs) | 值类型的记录,结合值语义和性能 | 小型数据结构 | 值类型,复制成本需考虑 |
全局 using 指令 | 全局导入命名空间 | 简化类型引用 | 需平衡代码可读性 |
概述
记录结构将记录特性扩展到值类型,结合值语义和性能。全局using
简化类型引用。
语法
记录结构: public record struct StructName(type1 Property1, ...);
全局 using: global using System;
示例代码
// 记录结构
public record struct Point(int X, int Y);
var point1 = new Point(1, 2);
var point2 = new Point(1, 2);
Console.WriteLine(point1 == point2); // True
var point3 = point1 with { X = 3 };
Console.WriteLine(point3); // Point { X = 3, Y = 2 }
// 全局 using(假设已在文件顶部)
Console.WriteLine("Hello, World!"); // 无需显式 using System
适用场景
值类型数据建模(记录结构)。 大型项目命名空间管理(全局 using)。
注意事项
记录结构复制成本需关注。 全局 using 需谨慎使用。
C# 11.0:必需成员, 泛型数学支持, 文件局部类型
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
必需成员 (required members) | 强制成员初始化 | 确保关键字段初始化 | 需配合初始化器或构造函数 |
泛型数学支持 | 静态抽象接口成员支持泛型运算 | 泛型算法库 | 需运行时支持(.NET 7+) |
文件局部类型 (file modifier) | 限制类型作用域至文件 | 隔离辅助类型 | 仅限文件作用域 |
概述
required
修饰符强制成员初始化。泛型数学支持通过接口实现数值运算。file
修饰符限制类型作用域。
语法
必需成员: public required type Property { get; set; }
泛型数学: interface INumber<T> { static abstract T operator +(T, T); }
文件局部类型: file class ClassName { ... }
示例代码
// 必需成员
public class Person
{
public required string Name { get; set; }
}
var person = new Person { Name = "Alice" };
Console.WriteLine(person.Name); // Alice
// 泛型数学支持
public interface INumber<T> where T : INumber<T>
{
static abstract T Add(T left, T right);
}
public readonly struct MyNumber : INumber<MyNumber>
{
public int Value { get; init; }
public MyNumber(int value) => Value = value;
public static MyNumber Add(MyNumber left, MyNumber right) => new(left.Value + right.Value);
}
MyNumber a = new(1);
MyNumber b = new(2);
var result = MyNumber.Add(a, b);
Console.WriteLine(result.Value); // 3
// 文件局部类型
file class Helper
{
public static void Log(string message) => Console.WriteLine(message);
}
Helper.Log("Test");
适用场景
API 设计(必需成员)。 泛型数值计算(泛型数学)。 代码生成(文件局部类型)。
注意事项
必需成员需明确初始化。 泛型数学需运行时支持。
C# 12.0:内联数组
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
内联数组 (Inline Arrays) | 固定大小数组结构,栈分配 | 高性能固定大小数组 | 固定大小,仅限结构体内 |
概述
内联数组通过[InlineArray]
特性定义固定大小数组结构,优化性能。
语法
[InlineArray(length)]
public struct StructName
{
private elementType _element0;
}
示例代码
[InlineArray(10)]
public struct Buffer
{
private int _element0;
}
Buffer buffer = new();
buffer[0] = 1;
buffer[9] = 10;
Console.WriteLine(buffer[0]); // 1
适用场景
高性能计算。 替代不安全固定缓冲区。
注意事项
固定大小,运行时不可调整。
C# 13.0:参数集合扩展, 引用结构接口支持, 部分属性
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
参数集合扩展 (params Span等) | 扩展params支持Span等 | 高性能参数传递 | 需确保Span生命周期 |
引用结构接口支持 | 允许ref struct实现接口 | 扩展ref struct能力 | 仍受ref struct限制 |
部分属性 (partial properties) | 支持partial类型部分属性 | 代码生成 | 需确保定义一致 |
概述
参数集合扩展支持Span<T>
等类型。ref struct
可实现接口。部分属性支持分文件定义。
语法
参数集合: void Method(params Span<T> spans);
引用结构接口: ref struct StructName : IInterface { ... }
部分属性: public partial type Property { get; set; }
示例代码
// 参数集合扩展
public void Process(params Span<int> spans)
{
foreach (var span in spans)
Console.WriteLine(string.Join(", ", span.ToArray()));
}
int[] numbers = [1, 2, 3];
Process(numbers.AsSpan(0, 2), numbers.AsSpan(2, 1)); // 1, 2 和 3
// 引用结构接口支持
public interface IBuffer
{
void Process();
}
ref struct Buffer : IBuffer
{
public Span<int> Data;
public Buffer(Span<int> data) => Data = data;
public void Process() => Data[0] = 10;
}
Buffer buffer = new(numbers.AsSpan());
buffer.Process();
Console.WriteLine(numbers[0]); // 10
// 部分属性
public partial class Person
{
public partial string Name { get; set; }
}
public partial class Person
{
public partial string Name { get => _name; set => _name = value; }
private string _name;
}
var person = new Person { Name = "Alice" };
Console.WriteLine(person.Name); // Alice
适用场景
高性能参数传递(参数集合)。 扩展 ref struct
(接口支持)。代码生成(部分属性)。
注意事项
参数集合需管理Span生命周期。 部分属性需确保一致性。
C# 14.0:field
关键字, 隐式 span 转换, nameof
增强, lambda 参数修饰符, partial 成员扩展, 空条件赋值
特性表格
类型/构造 | 描述 | 主要用途 | 注意事项 |
---|---|---|---|
field 关键字 |
允许在属性访问器中直接访问 backing field | 简化属性实现 | 可能与现有字段名冲突,需使用 @field 或 this.field 区分 |
隐式 span 转换 | 支持 Span<T> 、ReadOnlySpan<T> 与数组间的隐式转换 |
更自然地使用 span 类型 | 需注意 span 的生命周期 |
nameof 支持未绑定泛型 |
允许 nameof 使用未绑定泛型类型,如 nameof(List<>) |
泛型编程中的类型名称获取 | - |
lambda 参数修饰符 | 允许 lambda 参数使用 ref 、out 等修饰符,无需指定类型 |
增强 lambda 表达式的灵活性 | params 仍需指定类型 |
partial 构造函数和事件 | 扩展 partial 成员到实例构造函数和事件 | 分离定义和实现,适合代码生成 | 需确保 defining 和 implementing 声明一致 |
空条件赋值 | 允许在赋值左侧使用 ?. 和 ?[] ,仅在左侧非 null 时赋值 |
简化 null 检查 | 不支持 ++ 和 -- |
概述
C# 14.0(预计2025年随.NET 10发布,截至2025年4月为预览版)引入了一系列语言特性,旨在提高开发效率和代码可读性,包括 field
关键字、隐式 span 转换、nameof
增强、lambda 参数修饰符、partial 成员扩展和空条件赋值。虽然未引入全新数据类型,但这些特性显著增强了现有类型的用法。
field
关键字
概述
field
关键字允许在属性访问器中直接访问编译器生成的 backing field,无需显式声明。
示例代码
public class Person
{
public string Name
{
get => field;
set => field = value?.Trim();
}
}
var person = new Person { Name = " Alice " };
Console.WriteLine(person.Name); // Alice
适用场景
简化属性实现,特别是需要对 setter 进行处理时。
注意事项
如果类中已有名为 field
的字段,需使用@field
或this.field
区分。作为C# 13.0的预览特性,C# 14.0正式支持,详见field 关键字。
隐式 span 转换
概述
C# 14.0 为 Span<T>
和 ReadOnlySpan<T>
提供了与数组的隐式转换,使其使用更加自然。
示例代码
Span<int> span = new int[] {1, 2, 3};
int[] array = span.ToArray();
Console.WriteLine(string.Join(", ", array)); // 1, 2, 3
适用场景
高性能场景中,减少显式转换。 与数组和 span 类型交互。
注意事项
需确保 span 的生命周期管理,详见Span 转换。
nameof
支持未绑定泛型
概述
允许 nameof
操作符使用未绑定泛型类型。
示例代码
string listName = nameof(List<>);
Console.WriteLine(listName); // List
适用场景
泛型编程中,获取类型名称。
注意事项
简单但强大的增强,适合反射场景。
lambda 参数修饰符
概述
允许在 lambda 表达式中为参数添加修饰符,如 ref
、out
等,无需指定类型。
示例代码
var increment = (ref int x) => x++;
int num = 5;
increment(ref num);
Console.WriteLine(num); // 6
适用场景
需要在 lambda 中修改外部变量。
注意事项
params
仍需指定类型,详见lambda 表达式。
partial 构造函数和事件
概述
扩展 partial 成员到实例构造函数和事件,允许在 partial 类型中分离定义和实现。
示例代码
// File1.cs
public partial class MyClass
{
public partial MyClass(int x);
public partial event EventHandler MyEvent;
}
// File2.cs
public partial class MyClass
{
public partial MyClass(int x) { }
public partial event EventHandler MyEvent;
}
适用场景
代码生成场景,如 UI 设计器。
注意事项
需确保 defining 和 implementing 声明一致,详见partial 成员。
空条件赋值
概述
允许在赋值语句的左侧使用 ?.
和 ?[]
,仅当左侧非 null 时执行赋值。
示例代码
string? text = null;
text?.Length = 5; // 不执行赋值
List<int>? list = null;
list?[0] = 10; // 不执行赋值
list = new List<int> { 0 };
list?[0] = 10; // 执行赋值,list[0] = 10
Console.WriteLine(list[0]); // 10
适用场景
简化 null 检查,避免 NullReferenceException。
注意事项
不支持 ++
和--
操作,详见空条件赋值。
结语
C# 7.0至C# 14.0的类型系统新增内容涵盖了值元组、Span、ReadOnlySpan、Memory、ReadOnlyMemory、可空引用类型、记录、本机大小整数、记录结构、内联数组等数据类型,以及只读结构、引用结构、必需成员、泛型数学支持等增强。C# 14.0通过field
关键字、隐式 span 转换等特性进一步优化了现有类型的用法。这些特性满足了从高性能内存管理到类型安全建模的多种需求。资深C#工程师可根据场景选择类型,如使用Span优化性能,记录建模数据。由于C# 14.0尚在预览阶段,建议关注dotnet/roslyn以获取最新更新。
C#高性能开发之类型系统:从C# 7.0 到C# 14的类型系统演进全景的更多相关文章
- Java Web高性能开发(三)
今日要闻: Clarifai:可识别视频中物体 最近几年,得益于深度学习技术的发展,谷歌和Facebook等企业的研究人员在图形识别软件领域取得了重大突破.现在,一家名为Clarifai的创业公司则提 ...
- Java Web高性能开发(二)
今日要闻: 性价比是个骗局: 对某个产品学上三五天个把月,然后就要花最少的钱买最多最好的东西占最大的便宜. 感谢万能的互联网,他顺利得手,顺便享受了智商上的无上满足以及居高临下的优越感--你们一千块买 ...
- JavaWeb高性能开发(一)
今日要闻: 淘宝删差评产业链 在你给出"差评""中评"后不久,有人会偷偷登录你的淘宝账户,把你之前给过的评价删除或改成"好评".而这种人就是 ...
- Java Web 高性能开发,第 3 部分: 网站优化实战
这个系列的前两篇,介绍了前端的优化技术,这些技术秉承了前人至高无上的智慧,我只是负责吸收和传播.然而,这些技术一般也都是某某大型网站的技术经验,我们大部分人或许只能接触到相对小规模的网站,小规模的网站 ...
- .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)——转载
原文链接:https://blog.walterlv.com/post/dotnet-high-performance-reflection-suggestions.html ***** 大家都说反射 ...
- JavaScript高性能开发的十条建议
JavaScript高性能开发的十条建议 文/开发部 Dimmacro 编者按:javascript开发大部分程序员都做过,写出来的代码质量也千差万别,现在浏览器内嵌的解释器虽然效率已经很高了,但在客 ...
- Java Web 高性能开发,前端的高性能
Java Web 高性能开发,第 2 部分: 前端的高性能 Web 发展的速度让许多人叹为观止,层出不穷的组件.技术,只需要合理的组合.恰当的设置,就可以让 Web 程序性能不断飞跃.Web 的思想是 ...
- 原 .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
大家都说反射耗性能,但是到底有多耗性能,哪些反射方法更耗性能:这些问题却没有统一的描述. 本文将用数据说明反射各个方法和替代方法的性能差异,并提供一些反射代码的编写建议.为了解决反射的性能问题,你可以 ...
- CozyRSS开发记录18-番外之Atom1.0的支持
CozyRSS开发记录18-番外之Atom1.0的支持 1.对CozyRSS.Syndication批判一番 由于我工作的主要开发语言是c++,所以会看到我的c#代码写得非常朴素,很多语法糖都没有用上 ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
随机推荐
- Oracle用户的创建和授权
1 --创建用户.密码 2 create user infouser identified by "User@2022!"; 3 --授权连接数据库权限 4 grant conne ...
- 第15章 流与IO
第15章 流与IO 15.1 .NET 流的架构 .NET 流的架构主要包含三个概念:** 后台存储 . 装饰器 以及 流适配器 **,如图所示: C7.0 核心技术指南 第7版.pdf - p655 ...
- 数字先锋 | 车企,出海!天翼云AOne擦亮车企“智慧服务”新名片!
近年来,中国汽车市场迎来巨变,消费者的消费习惯不断变迁,价格战愈演愈烈......如何紧跟数字化转型步伐,实现稳健经营,成为车企所面临的时代命题. 作为一家科技型制造企业,某车企主营业务涉及汽车及核心 ...
- 如何利用cursor+deepseek来最大程度减少组件库的学习成本!
在当今的软件开发领域,开发者们面临着不断提升开发效率与降低上手成本的挑战.本文档的核心目的,便是助力开发者们实现这一目标,特别是通过巧妙运用组件官网文档,并结合 Cursor 与 DeepSeek 等 ...
- 阿里的DataV和QuickBi区别
首先说下DataV吧 分为老版和新版(二者之间没有什么太大的差别,存在的基本都是组件上的配置或是更多不同组件的新增,但是如果你是在项目上进行开发,你首先要知道客户用的DataV用的是什么版本,如果你们 ...
- 发那科焊接机器人M-10iA维修总结
发那科作为工业机器人制造商,其焊接机器人产品广泛应用于各种工业领域.然而,随着时间的推移,焊接机器人可能会出现故障,因此了解发那科焊接机器人M-10iA维修知识显得尤为重要. 一.日常法那科机械手维护 ...
- 普通人如何靠 AI 副业,1 个月实现月薪 3 万 +
在物价飞涨.经济低迷的今天,仅靠死工资,却有着不固定的开销?房贷.车贷.孩子的教育费用-- 望着日益增长的开销,你是否也在夜深人静时,为钱包的羞涩而发愁?无数次幻想过拥有一份高收入的副业,却始终在迷茫 ...
- div剩余高度自动填充满
这边采用弹性布局来处理 在需要被填充满的div上设置display:flex;,然后根据你所需要填充宽度(flex-direction:column;)高度(flex-direction:row;)设 ...
- docker - [14] redis集群部署
本章节是在一个服务器上进行演示 一.准备工作 (1)创建redis集群使用的网络:redis-net docker network create redis-net --subnet 172.38.0 ...
- 【目标检测】一、初始的R-CNN与SVM
1.流程 为什么要用SVM而不是CNN最后一层的softmax? 取什么模型必然是有标准衡量,这个流程取得是书上[4]写的,作者说他得实验证明SVM比FC的mAP要高,所以我流程暂且这样画了. R-C ...