当前位置: 首页 > news >正文

【unity c#】深入理解string,以及不同方式构造类与反射的性能测试(基于BenchmarkDotNet)

出这篇文章的主要一个原因就是ai回答的性能差异和实际测试完全不同,比如说是先获取构造函数再构造比Activator.CreateInstance(type)快,实际却相反
对测试结果的评价基于5.0,因为找不到unity6确切使用的net版本,根据c#9推测是net5.0

起因:看到animancer对string的描述,我开始纠结起来要不要使用,于是有此文章
省流版就是
因为字符串常量池,字面量和方法参数都是直接比较引用,而且无论"string"+"string"还是两个相同长度不同内容的字符串都是比较的引用,如果引用不同,会比较长度,只有在使用变量存字符串,并且运行时动态修改,导致引用不同

  1. 只要不使用变量存字符串,并且运行时动态修改,就可以放心用string
  2. 反射用委托
  3. 构造用表达式树或者Activator.CreateInstance(反正不会经常调用)
  4. 拼接字符串用StringBuilder
  5. 有时间纠结性能不如多做两个玩法
    stringbuilder和字符串常量池都是学java时的遗产,但学c#好像没被提到过,所以在这里提一嘴
    在这里插入图片描述StringReference 本质是 通过字典缓存引用比较,也就是说,如果通过动态字符串获取缓存,仍然会在取值时执行一次字符比较判断键是否相等。如果BenchmarkDotNet是可信的,那么StringReference可能 并没有起到提高效率的效果。反而因为隐式转换额外多消耗了一点

补充:

所以最终我决定放弃包装string,如果有需要扩展的就直接用【扩展方法】就好了
不过通过隐式类型转换+字典的缓存方式也让人大开眼界,留个印象说不定哪天用得上

BenchmarkDotNet可参:https://blog.csdn.net/x740073529/article/details/119934597
安装可参:https://www.cnblogs.com/WilsonPan/p/12904664.html
视频可参:https://www.bilibili.com/video/BV1DM411T7rb
简单来说就是安装包,在main入口执行,记得将运行设置为运行模式而不是调试模式:
在这里插入图片描述

为了8和5兼容需要删除自动生成全局using的设置:ImplicitUsings。右键,编辑项目文件可以找到

<PropertyGroup><OutputType>Exe</OutputType><TargetFrameworks>net8.0;net5.0</TargetFrameworks><Nullable>enable</Nullable>
</PropertyGroup>

String

主要还是参考作用,真正真实的结果只能到unity实际测试了

结论

  • 前置知识:直接用字面量(= ‘abc’)是得到字符串常量池中的引用,所以相同字面量的字符串引用地址相等。而new或者拼接动态字符串才会开辟新的内存空间
  • 常量形式的string哪怕是"string"+"string"的形式,也是被字符串常量池优化过的,相当于直接比较引用
  • 字符串的等号应该是被重写的,调用equals,并且优先比较引用,也就时候说,只有在使用变量存字符串,并且运行时动态修改,并且长度不同,才会低效
  1. 查找字符串为键的字典:取hash比较,快
  2. 查找字符串为键的字典,取值时动态拼接字符串多出的时间消耗约等于变量拼接常量再比较,意味着除了hash计算还有一次字符比较的操作
  3. 查找值类型为键的字典:遥遥领先
  4. 引用类型作为键:比字符串稍快
  5. 包装字符串为类的效果:比引用类型稍慢
  6. 动态拼接字符串来查找: 不缓存则较慢
  7. 常量字符串比较:比引用比较更快,可能有优化吧
  8. 不同常量不同长度字符串比较:稍慢,应该是判断了字符串长度
  9. 拼接常量字符串:和常量比较一样,看来是自动优化了
  10. 变量拼接常量再比较(normal3):很慢。这里应该是比较的字符
  11. 不同常量比较:快

这里是总览,命名不规范,建议和代码对照看
在这里插入图片描述

源码

在 .NET 5 之前,很多基础类型(例如 string)的实现是在 C++ 编写的
所以只能看net8的来参考了

 public override bool Equals([NotNullWhen(true)] object? obj){if (ReferenceEquals(this, obj))return true;if (!(obj is string str))return false;if (this.Length != str.Length)return false;return EqualsHelper(this, str);}private static bool EqualsHelper(string strA, string strB)
{Debug.Assert(strA != null);Debug.Assert(strB != null);Debug.Assert(strA.Length == strB.Length);return SpanHelpers.SequenceEqual(ref Unsafe.As<char, byte>(ref strA.GetRawStringData()),ref Unsafe.As<char, byte>(ref strB.GetRawStringData()),((uint)strA.Length) * sizeof(char));
}
补充
  1. 不同常量相同长度字符串:引用级
  2. 每个字符比较:比动态拼接快。推测是少了一系列引用比较的缘故
  3. 比较常量的hash:不如每个字符比较一遍
  4. Equals比较不同常量:比引用慢,比hash快,比较的是字符?
  5. Equals比较相同常量:五代比等号慢,说明等号有特殊处理
    在这里插入图片描述
    可以看到5代的Equals被8代薄纱,可能是把等号的判断移到Equals了
    在这里插入图片描述
    看其他博客说 动态拼接的比较方式为比较两个字符串的第一个字符:相等则比较第二个,实际测试并不是,比较字符串时改变差异字符的位置没有影响性能,估计是
[Benchmark]
public void xiangdengNormal7()
{for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf" == "asdasdfasdfasdfsafasdp";}
}
[Benchmark]
public void xiangdengNormal8()
{string a = "asdasdfasdfasdfsafasdf";string b = "asdasdfasdfasdfsafasdf";for (int i = 0; i < N; i++){for (int j = 0; j < a.Length; j++){var t = a[j] == b[j];}}
}
[Benchmark]
public void xiangdengNormal9()
{ for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf".GetHashCode() == "asdasdfasdfasdfsafasdp".GetHashCode();}
}
[Benchmark]
public void xiangdengNormal10()
{for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf".Equals("asdasdfasdfasdfsafasdp");}
}
[Benchmark]
public void xiangdengNormal12()
{for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf".Equals("asdasdfasdfasdfsafasdf");}
}
不用循环
  • 这里是没用循环的结果,缓存每用上导致结果不准确,所以用hash的结果偏慢。但也反映出hash和string常量引用不同,反而丢失了常量池的优化
  • 可以看到net8 比较动态字符串也快了三四倍
  • 其他:模板字符串消耗更高
    在这里插入图片描述

测试getHashCode的消耗

可以看出来字典查找的损耗就是源自于此,而且每次都是重新获取hash

[Benchmark]
public void getHash1()
{"asdasdfasdfasdfsafasdf".GetHashCode();
}
[Benchmark]
public void getHash2()
{stringHash.GetHashCode();
}

在这里插入图片描述

测试代码

[SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net50)]   // 在Net5.0测试(unity6 => c#9 推测=> net5.0)
[SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net80)]
public class StringTest
{// 测试数据量private const int N = 100;// 测试用的字符串和 StringHash 字典private Dictionary<string, string> stringDict;private Dictionary<int, int> intDict;private Dictionary<YourClass, int> objDict;private YourClass obj = new YourClass();private Dictionary<StringHash, StringHash> stringHashDict;private StringHash stringHash = "asdasdfasdfasdfsafasdf";// 引用应该是相同的  用字典缓存了的private StringHash stringHash2 = "asdasdfasdfasdfsafasdf";private string key = "Value";// 初始化测试数据[GlobalSetup]public void Setup(){key += "10";stringDict = new Dictionary<string, string>(N);stringHashDict = new Dictionary<StringHash, StringHash>(N);intDict = new Dictionary<int, int>(N);objDict = new Dictionary<YourClass, int>(N);// 插入数据objDict.Add(obj, 1); // 对象字典for (int i = 0; i < N; i++){string value = $"Value{i}";stringDict.Add(value, value); // 字符串字典stringHashDict.Add(value, value); // StringHash 字典intDict.Add(i, i); // 整数字典}}// 字符串字典插入性能//[Benchmark]//public void StringDictInsertion()//{//    for (int i = 0; i < N; i++)//    {//        string value = $"Value{i}";//        stringDict[value] = value;//    }//} StringHash 字典插入性能//[Benchmark]//public void StringHashDictInsertion()//{//    for (int i = 0; i < N; i++)//    {//        //string value = $"Value{i}";//        stringHashDict[new StringHash(value)] = new StringHash(value);//    }//}// 字符串字典查找性能[Benchmark]public void StringDictLookup(){for (int i = 0; i < N; i++){string value = "Value" + i;stringDict.TryGetValue(value, out _);}}[Benchmark]public void StringDictLookup2(){for (int i = 0; i < N; i++){string value = "Value10";stringDict.TryGetValue(value, out _);}}[Benchmark]public void IntDictLookup(){for (int i = 0; i < N; i++){intDict.TryGetValue(10, out _);}}[Benchmark]public void ObjDictLookup(){for (int i = 0; i < N; i++){objDict.TryGetValue(obj, out _);}} 动态字符串字典查找性能[Benchmark]public void StringDictLookupByDynamic(){for (int i = 0; i < N; i++){string value = "Value";stringDict.TryGetValue(value + "10", out _);}}[Benchmark]public void StringDictLookupByDynamic2(){for (int i = 0; i < N; i++){ stringDict.TryGetValue(key, out _);}}// StringHash 字典查找性能[Benchmark]public void StringHashDictLookup(){for (int i = 0; i < N; i++){//string value = $"Value{i}";stringHashDict.TryGetValue(new StringHash("Value10"), out _);}}[Benchmark]public void StringHashDictLookup2(){for (int i = 0; i < N; i++){//这里是缓存的stringHashDict.TryGetValue("Value10", out _);}}[Benchmark]public void xiangdengNormal(){for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf" == "asdasdfasdfasdfsafasdf";}}[Benchmark]public void xiangdengNormal2(){for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf" == "asdasdfasdfasdf" + "safasdf";}}[Benchmark]public void xiangdengNormal3(){for (int i = 0; i < N; i++){string a = "asdasdfasdfasdf";var t = "asdasdfasdfasdfsafasdf" == a + "safasdf";}}[Benchmark]public void xiangdengNormal4(){for (int i = 0; i < N; i++){var t = "asdasdfasdfasdfsafasdf" == "asdasdfasdfasdfsafasdfasfaa";}}[Benchmark]public void xiangdengNormal5(){for (int i = 0; i < N; i++){string a = "asdasdfasdfasdfsafasdf";string b = "asdasdfasdfasdfsafasdfasfaa";var t = a == b;}}[Benchmark]public void xiangdengHash(){for (int i = 0; i < N; i++){var t = stringHash == "asdasdfasdfasdfsafasdf";}}[Benchmark]public void xiangdengHash2(){for (int i = 0; i < N; i++){var t = stringHash == "asdasdfasdfasdfsafasdfasfaa";}}[Benchmark]public void xiangdengRefrence(){var t = stringHash == stringHash2;}[Benchmark]public void xiangdengInt(){var t = 123 == 123;}
}[Serializable]
public class StringHash : IComparable<StringHash>
{// 字段 private readonly string name;public int hash;private static readonly Dictionary<string, StringHash> StringHashDic = new(256);/// <summary>/// 获取或添加/// </summary>/// <param name="value"></param>/// <returns></returns>public static StringHash Get(string value){if (value is null) return null;if (!StringHashDic.TryGetValue(value, out var reference))StringHashDic.Add(value, reference = new(value));return reference;}// 构造函数public StringHash(string name){this.name = name;hash = HashCode.Combine(name);// 对于相同字符串,生成相同hash码// hash =  Animator.StringToHash(name);}// 重写隐式转换// 在 string 类型和自定义的 StateHashName 类型之间进行自动转换  就可以直接=[MethodImpl(MethodImplOptions.AggressiveInlining)]public static implicit operator StringHash(string value) => Get(value);public static implicit operator string(StringHash value) => value?.name;// 覆盖 ToString 方法// 特性:尽可能将方法内联化   比委托调用快十倍[MethodImpl(MethodImplOptions.AggressiveInlining)]public override string ToString() => name;// 重载 == 运算符public static bool operator ==(StringHash left, StringHash right){if (ReferenceEquals(left, null))return ReferenceEquals(right, null);return left.Equals(right);}// 重载 != 运算符public static bool operator !=(StringHash left, StringHash right){return !(left == right);}// 重写 Equals 和 GetHashCode 方法  //public override bool Equals(object obj)//{//    if (ReferenceEquals(this, obj)) return true;//    if (obj is StringHash other)//    {//        // 检查哈希值//        if (hash != other.hash)//            return false;//        return true;//        // 哈希值相等时,进一步比较字符串内容 处理hash碰撞//        //return name == other.name;// == 对于 null 会非常安全,但 Equals 可能会抛出异常//    }//    return false;//}// 会被字典调用// 如果键冲突,会调用Equals public override int GetHashCode(){return hash;}// 比较方法public int CompareTo(StringHash other) => name.CompareTo(other?.name);
}

构造类测试

反射经常能简化代码,但也有性能损耗,索性可以避免,委托只是其中一种方式。

  1. 带缓存表达式树调用构造函数(委托) : 只比正常慢了一点
  2. 表达式树(委托)
  3. 正常构造
  4. 通过反射获取构造方法再调用:慢了十倍以上
  5. 反射+强制类型转换:慢了5倍的样子
  6. 反射+as 类型转换:as确实比强转慢一点,但不多
  7. 泛型反射:和反射一样
    结果: net8.0对反射似乎有不小的优化,可惜unity版本更不上
    在这里插入图片描述
    测试代码
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Linq.Expressions;
using System;  [MemoryDiagnoser]
[SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net50)]   // 在Net5.0测试(unity6 => c#9 推测=> net5.0)
[SimpleJob(BenchmarkDotNet.Jobs.RuntimeMoniker.Net80)]
public class TestClass
{private Action _delegate;private event Action _event;int iterations = 10000;static void Main(string[] args)//main函数{// 运行 BenchmarkTest 里标记为 Benchmark 的方法,比较它们的性能var summary = BenchmarkRunner.Run<TestClass>();Console.WriteLine(summary);} private Func<YourClass> constructorDelegate;[GlobalSetup]public void Setup(){var type = typeof(YourClass);// 获取无参数的构造函数var constructor = type.GetConstructor(Type.EmptyTypes);// 创建一个表达式树,表示调用构造函数的操作var newExpression = Expression.New(constructor);// 创建一个 Lambda 表达式,指定返回类型为 YourClassvar lambda = Expression.Lambda<Func<YourClass>>(newExpression);// 编译表达式树,得到一个委托constructorDelegate = lambda.Compile();}[Benchmark]public void biaodashiHuancun(){YourClass obj = constructorDelegate();}[Benchmark]public void biaodashi(){var type = typeof(YourClass);// 获取无参数的构造函数var constructor = type.GetConstructor(Type.EmptyTypes);// 创建一个表达式树,表示调用构造函数的操作var newExpression = Expression.New(constructor);// 创建一个 Lambda 表达式,指定返回类型为 YourClassvar lambda = Expression.Lambda<Func<YourClass>>(newExpression);// 编译表达式树,得到一个委托var constructorDelegate = lambda.Compile();YourClass obj = constructorDelegate();} [Benchmark]public void Normal(){YourClass obj = new YourClass();}[Benchmark]public void gouzao(){var type = typeof(YourClass);var constructor = type.GetConstructor(Type.EmptyTypes); YourClass obj = constructor.Invoke(null) as YourClass;}[Benchmark]public void fanshe(){var type = typeof(YourClass); // 请替换为你的类 YourClass? obj = (YourClass)Activator.CreateInstance(type);}[Benchmark]public void fansheAs(){var type = typeof(YourClass); // 请替换为你的类 YourClass? obj = Activator.CreateInstance(type) as YourClass;}[Benchmark]public void fansheFanxing(){var type = typeof(YourClass);YourClass? obj = Activator.CreateInstance<YourClass>();}}//省略了字段
public class YourClass
{ public YourClass(){ }
}

额外测试

空类测试

  1. 类的属性是否影响构造消耗:是
  2. as的消耗具体多大:可以忽略,甚至更快了
    在这里插入图片描述

十几个字段的类

  1. as转换为接口和as转换为类消耗差距: 差不多
  2. as和is消耗:差不多
    在这里插入图片描述在这里插入图片描述

代码:

[Benchmark]
public void fanshe()
{var type = typeof(YourClass); // 请替换为你的类 object obj = Activator.CreateInstance(type);
}
[Benchmark]
public void fansheAs()
{var type = typeof(YourClass); // 请替换为你的类 YourClass? obj = Activator.CreateInstance(type) as YourClass;
}
[Benchmark]
public void fansheAsInterface()
{var type = typeof(YourClass); // 请替换为你的类 IYourInterface? obj = Activator.CreateInstance(type) as IYourInterface;
}
[Benchmark]
public void TestIS()
{var type = typeof(YourClass); // 请替换为你的类 _ = Activator.CreateInstance(type) is IYourInterface;
}

反射测试

参考:https://blog.walterlv.com/post/create-delegate-to-improve-reflection-performance.html

  1. 直接调用
  2. 通过方法(委托)调用:慢了十倍 (可能是有额外的检查)
  3. 通过委托调用:和通过方法差不多
  4. 通过缓存的反射方法:慢了百倍
  5. 通过反射:慢了两百倍
    在这里插入图片描述
代码
public class Fanshe
{private StubClass instance;private MethodInfo method;private Func<int, int> pureFunc;private Func<int, int> func;// 初始化测试数据[GlobalSetup]public void Setup(){instance = new StubClass();method = typeof(StubClass).GetMethod(nameof(StubClass.Test), new[] { typeof(int) });pureFunc = value => value;// 使用反射创建一个委托func = InstanceMethodBuilder<int, int>.CreateInstanceMethod(instance, method);}// 直接调用[Benchmark]public void DirectCall(){var result = instance.Test(5);}// 使用 Func 委托调用[Benchmark]public void FuncCall(){var result = pureFunc(5);}// 使用反射创建的委托调用[Benchmark]public void DelegateFromReflection(){var result = func(5);}// 使用缓存的反射方法调用[Benchmark]public void CachedReflectionCall(){var result = method.Invoke(instance, new object[] { 5 });}// 使用每次都反射查找的方法调用[Benchmark]public void DirectReflectionCall(){var result = typeof(StubClass).GetMethod(nameof(StubClass.Test), new[] { typeof(int) })?.Invoke(instance, new object[] { 5 });}
}

相关文章:

【unity c#】深入理解string,以及不同方式构造类与反射的性能测试(基于BenchmarkDotNet)

出这篇文章的主要一个原因就是ai回答的性能差异和实际测试完全不同&#xff0c;比如说是先获取构造函数再构造比Activator.CreateInstance(type)快&#xff0c;实际却相反 对测试结果的评价基于5.0&#xff0c;因为找不到unity6确切使用的net版本&#xff0c;根据c#9推测是net5…...

VSCode 插件开发实战(八):创建和管理任务 Task

前言 VSCode 的扩展能力使得开发者能够根据个人需求定制工作环境&#xff0c;自定义插件和任务管理是 VSCode 强大功能的一部分&#xff0c;通过这些功能&#xff0c;开发者可以自动化常见工作流&#xff0c;简化日常开发任务&#xff0c;提高整体开发效率。本文将详细介绍如何…...

在 Node.js 中正确处理 `async/await` 及数组迭代

在使用 Node.js 开发应用程序时&#xff0c;我们常常需要处理异步操作。例如&#xff0c;当我们从数据库获取数据、调用外部API或执行文件读取时&#xff0c;这些操作都可能需要一些时间才能完成。在这种情况下&#xff0c;我们通常会使用 async/await 语法来简化异步编程的复杂…...

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——13使用Resnet-Bin

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——13使用Resnet-Bin ​ 根据前面的内容&#xff0c;目前已经可以获取到resnet的bin模型 1 .Resnet的bin测试 ​ 这里给大家一个测试视频里面黑线的demo&#xff0c;大家可以用来测试自己的黑线识别精度 …...

FFmpeg第三话:FFmpeg 视频解码详解

FFmpeg 探索之旅 一、FFmpeg 简介与环境搭建 二、FFmpeg 主要结构体剖析 三、FFmpeg 视频解码详解 FFmpeg第三话&#xff1a;FFmpeg 视频解码详解 FFmpeg 探索之旅前言一、视频解码基础二、FFmpeg 关键 API 深度剖析&#xff08;一&#xff09;avformat_open_input()&#xff…...

解决 vue3 中 echarts图表在el-dialog中显示问题

原因&#xff1a; 第一次点开不显示图表&#xff0c;第二次点开虽然显示图表&#xff0c;但是图表挤在一起&#xff0c;页面检查发现宽高只有100px,但是明明已经设置样式宽高100% 这可能是由于 el-dialog 还没有完全渲染完成&#xff0c;而你的 echarts 组件已经开始尝试渲染图…...

C++ OpenGL学习笔记(4、绘制贴图纹理)

相关链接&#xff1a; C OpenGL学习笔记&#xff08;1、Hello World空窗口程序&#xff09; C OpenGL学习笔记&#xff08;2、绘制橙色三角形绘制、绿色随时间变化的三角形绘制&#xff09; C OpenGL学习笔记&#xff08;3、绘制彩色三角形、绘制彩色矩形&#xff09; 通过前面…...

关于我的Java考试被老师挂掉的这件事......

目录 1.事情起源 2.问题出现 3.最后的考试结果 4.问题如何解决的 5.此件事情引发我的思考 1.事情起源 现在是2024-12-25中午的13:08分&#xff0c;我于今天上虞结束了这个学期的Java课程的学习&#xff0c;上午的课程内容就是开始&#xff0c;使用MVC实现对于题目要求的这…...

Websocket客户端从Openai Realtime api Sever只收到部分数据问题分析

目录 背景 分析 解决方案 背景 正常情况下&#xff0c;会从Openai Realtime api Sever收到正常的json数据,但是当返回音频数据时&#xff0c;总会返回非json数据。这是什么问题呢&#xff1f; 分析 期望的完整响应数据如下&#xff1a; {"session": {"inp…...

Unity 6 中的新增功能

Unity 6 是 Unity 的最新版本。 一、编辑器和工作流程 Unity 6 中引入的更改 在 Linux 上实现了将文件和资源从 Unity 拖放到外部应用程序的功能。将 Asset Manager for Unity 包添加到 Package Manager > Services > Content Management 部分中。此包允许用户轻松浏览…...

[ComfyUI]颜色提取插件,Flux专属,让出图更加可控

一、介绍​ 今天介绍这个好玩的插件 ComfyUI APQNodes&#xff0c;默认的Flux模型是无法理解准确的颜色代码。​ 而这个插件可以帮我忙将输入的十六进制颜色代码转换为 FLUX.1 Dev 已知的最相似的颜色名称&#xff08;来自预先测试的 155 个颜色名称&#xff09;。​ ​ 所以就…...

【magic-dash】01:magic-dash创建单页面应用及二次开发

文章目录 一、magic-dash是什么1.1 安装1.2 使用1.2.1 查看内置项目模板1.2.2 生成指定项目模板1.2.3 查看当前magic-dash版本1.2.4 查看命令说明1.2.5 内置模板列表二、创建虚拟环境并安装magic-dash三、magic-dash单页工具应用开发3.1 创建单页面项目3.1.1 使用命令行创建单页…...

ChatGPT等大语言模型与水文水资源、水环境领域的深度融合

聚焦GPT等大语言模型与水文水资源领域的深度融合&#xff0c;通过系统化内容与实践案例&#xff0c;讲解如何高效完成时间序列分析、空间数据处理、水文模型优化以及智能科学写作等任务。同时&#xff0c;展示AI在高级机器学习模型开发、资源优化算法编程与模型微调中的最新应用…...

机器学习连载

1 机器学习基础知识 机器学习&#xff08;Machine learning&#xff09;是人工智能的子集&#xff0c;是实现人工智能的一种途径&#xff0c;但并不是唯一的途径。它是一门专门研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已…...

linux查看天气预报

wttr.in 是一个简单且功能强大的命令行天气查询工具&#xff0c;实现了命令行下查看天气的炫酷效果。 开源地址&#xff1a;GitHub - chubin/wttr.in: :partly_sunny: The right way to check the weather 一. 什么是 wttr.in&#xff1f; wttr.in 是一个基于 Web 的命令行天…...

minikube start --driver=docker --force

minikube start --driver=docker --force 😄 minikube v1.34.0 on Debian 11.7 (amd64) ❗ minikube skips various validations when --force is supplied; this may lead to unexpected behavior ✨ Using the docker driver based on user configuration 🛑 The…...

游戏引擎学习第58天

发现一个vscode Log 断点的用法 回顾 我们正在继续推进工作&#xff0c;之前做了一些测试和清理工作&#xff0c;但还有一件事没有完成&#xff0c;因此我们还没有完全回到功能平衡的状态。昨天我们已经为实体做了空间划分&#xff0c;所以接下来的目标是继续完成这部分工作&a…...

我用火语言RPA生成EXE可执行文件,并使用激活码对EXE进行管理

火语言RPA&#xff0c;不仅可以生成EXE独立可执行文件&#xff0c;还可以使用激活码的功能对EXE进行管理&#xff0c;限制激活类型&#xff1a;在线、离线,EXE有效天数等进行管理&#xff0c;有限制的自由才是真正的自由&#xff01; 生成EXE的时候选择App注册码验证类型 当分享…...

【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版 (1)11

文章目录 一、算法概念11二、算法原理&#xff08;一&#xff09;感知机&#xff08;二&#xff09;多层感知机1、隐藏层2、激活函数sigma函数tanh函数ReLU函数 3、反向传播算法 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、MLP分类任务实…...

32位MCU主控智能电表方案

智能电表作为电网数据采集的核心设备&#xff0c;承担着至关重要的角色。它主要用于采集、计量和传输原始的电能数据&#xff0c;确保电力系统的高效运行。该设备配备了多种通讯接口&#xff0c;如RS485和以太网&#xff0c;使得用户能够轻松进行用电检测、集中抄表以及电力管理…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...