ZLogger 高性能日志库

Unity中大型项目日志升级:ZLogger零GC高性能实践 日志系统是游戏客户端可观测性的核心基础设施,其性能与稳定性直接影响开发效率与线上质量。传统Debug.Log同步阻塞、高频GC、无结构化等缺陷,在中大型Unity项目中极易引发卡顿、热更失败甚至崩溃。ZLogger通过异步无锁环形队列、结构化日志模板、零GC分配设计,实现微秒级延迟与内存可控性,显著提升真机帧率与编辑器响应。结合命名空间分级过滤、热更安全重载、iOS/Android平台专项适配等工程实践,它已成为千万级DAU手游团队构建生产级日志管道的关键选型。 阅读详情

github源码:https://github.com/Cysharp/ZLogger/tree/master

作者两篇文章1(部分旧的不适用):https://neuecc.medium.com/zlogger-zero-allocation-logger-for-net-core-and-unity-d51e675fca76

作者两篇文章2:https://neuecc.medium.com/zlogger-v2-architecture-leveraging-net-8-to-maximize-performance-2d9733b43789

C#10 自定义内插字符串:https://devblogs.microsoft.com/dotnet/string-interpolation-in-c-10-and-net-6/

C# 源代码生成器简介:https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/


概述

  • 高性能;支持模板配置;可以动态生成日志代码的日志库。

  • 可以解决常见unity日志问题:

    • 根据级别开关日志。

    • 字符串参数装箱问题。

    • 日志屏蔽不全的参数导致没必要的调用。

    • 线程异步的日志。

  • 可扩展:输出多个文件,自动生成额外参数。


和传统对比

日志开关统一

  • 平常开发打log没有统一日志库时,需要自己定义开关,通常也会漏开关,不受控。要么加宏开关,要么自己定义变量。
// 使用宏,需要代码头部定义宏,或者工程配置宏。
// 不用时,没有性能消耗,因为代码不会编译进去。就是不方便统一管理。
[Conditional("DEBUG_LOG")]
public static void DebugLog1(string str)
{
    Debug.Log($"DebugLog: {str}");
}
// 编译时,如果宏没开启,这行直接不会编译。
DebugLog1($"hello {id}");

// 自定义开关,开关可以统一。
// 不用时,还是会编译,如果参数会执行,有额外不必要开销。
// 在外面调用if判断也行,但得在所有打印日志前加if,大概率会漏。
public static void DebugLog2(string str)
{
    if (enable)
    {
         Debug.Log($"DebugLog: {str}");
    }
}
// 无论是否enable,这里都已经进行了字符串拼接了
DebugLog2($"hello2 {id}");
  • ZLogger加了一层日志包装,每个日志管理可以各自控制开关。
using var loggerFactory = LoggerFactory.Create(logging =>
{        
    // 设置输出日志的等级
    logging.SetMinimumLevel(LogLevel.Warning);
});

// 普通Log不会执行,包括参数,在编译时会调整
logger.Log(LogLevel.Information, $"Log {id}");

字符串装箱问题

  • 传统日志没有特殊处理,就是String.Format处理字符串,然后传给Debug.Log方法。
    在这里插入图片描述

  • ZLogger,通过C#的自定义内插字符串(InterpolatedStringHandler),实现对特殊参数用泛型代替,避免装箱操作。源码在:ZLoggerInterpolatedStringHandler.cs
    在这里插入图片描述

实现原理

在这里插入图片描述

1、2:初始化日志信息,字符串信息,判断是否开启

在这里插入图片描述

3:从池子里取或创建字符串模板

  • $"ZLog Hello {name} your id is {id}" 的模板:

  • ["ZLog Hello ", null, " your id is ", null]
    在这里插入图片描述

4:记录上下文,方法名,文件行号等

5:输出字符串

在这里插入图片描述
在这里插入图片描述

MagicalBox

  • MagicalBox:用来避免装箱,装任意数据
    在这里插入图片描述

编译时自动生成格式化日志代码

  • 需要编译c#版本preview版本(csc.rsp文件),LangVersion.props 改版本 11

  • 比起上面的日志生成,这个更高效,但需要额外写代码,也不保证调试正常,毕竟unity没直接支持。

  • ZLoggerMessage:https://github.com/Cysharp/ZLogger/tree/master?tab=readme-ov-file#zloggermessage-source-generator

  • 类似.net支持的: https://learn.microsoft.com/en-us/dotnet/core/extensions/logger-message-generator

  • https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/

在这里插入图片描述


System.Span<T>

  • 常用于直接取数组的一段数据,直接取得相同地址数据,不会额外分配内存。比如可以代替String.SubString()的功能,且不生成新的字符串。

    • 比如将 “DateTime.Now:@date:yyyy-MM-dd”,分前后两段

    在这里插入图片描述

  • 也可以用于说明数组只读性,System.ReadOnlySpan<T>:

    在这里插入图片描述

  • 操作一些编码

byte[] buffer = new byte[1024]; 
Span<byte> header = buffer.AsSpan(0, 128); // 取前128字节 
Span<byte> body = buffer.AsSpan(128);    
  • 分配临时栈内存
Span<int> stackData = stackalloc int[10]; // 栈上分配
for (int i = 0; i < stackData.Length; i++)     
{         
    stackData[i] = i;     
}

Unity高性能日志方案:ZLogger零分配与结构化实践 日志系统是游戏客户端稳定性与可维护性的基础设施,其性能瓶颈常源于字符串拼接、同步I/O和非结构化输出。ZLogger通过零分配(zero-allocation)日志事件构造、异步双缓冲刷盘及原生结构化(JSON)日志设计,显著降低GC压力与主线程阻塞风险。在Unity中,它直面Scripting Runtime兼容性、IL2CPP支持、真机沙盒权限等工程挑战,提供可分级过滤、动态开关、线程安全上下文注入等生产就绪能力。尤其适用于中大型Unity项目——当Debug.Log引发编辑器卡顿、CI构建失败或玩家闪 阅读详情

相关推荐

ZLogger:用于.NET Core和Unity的零分配TextStrcutured记录器,建立在Microsoft.Extensions.Logging的基础上

ZLogger žERO分配文本/结构化记录仪.NET的核心和团结,建立在Microsoft.Extensions.Logging的顶部。 记录到标准输出非常重要,尤其是在容器化时代(在-Logs说应该写到stdout》中进行了描述),但是传统上它的性能一直很慢,但是没有人关心它。它还支持文本日志和结构化日志,这在云日志管理中很重要。 ZLogger由我们的零分配字符串生成器直接写为UTF8。此外,还使用了完整的泛型,结构和缓存来实现最佳性能。默认选项通过异步和缓冲设置为最佳性能,因此您不必担心记录器设置。 ZLogger直接建立在Microsoft.Extensions.Logging之上。通过没有单独的记录器框架层,我们可以提取更好的性能。除了ConsoleLogging外,我们还提供FileLogger , RollingFileLogger和StreamLogger 。它们也

ZLogger 使用教程

ZLogger 是一个为 .NET 和 Unity 设计的零分配文本/结构化日志库,支持字符串插值和源代码生成器。它建立在 Microsoft.Extensions.Logging 之上,旨在提供高性能的日志记录解决方案。ZLogger 通过直接输出 UTF8 格式的日志,避免了传统日志架构中的编码开销,从而显著提高了日志记录的性能。 ## 2. 项目快速启动 ### 安装 ZLogger ...

gitblog_00435的博客 1306

实测有效防止colab自动断开连接

实测有效防止colab自动断开连接

Thebest_jack的博客 1万+

探索ZLogger:高性能的.NET和Unity日志库

探索ZLogger:高性能的.NET和Unity日志库 ZLogger Zero Allocation Text/Structured Logger for .NET with StringInterpolation and Source Generator, built on top of a Microsoft.Ex...

gitblog_00014的博客 569

从USB 2.0到USB 3.x:Synopsys SVT USB VIP配置避坑与接口选择指南

本文详细解析了从USB 2.0到USB 3.x的Synopsys SVT USB VIP配置要点,涵盖协议版本选择、物理接口匹配及UVM层次化架构实现。重点介绍了layering sequence的配置技巧和常见问题解决方案,帮助验证工程师高效避坑并优化验证流程。

weixin_42653691的博客 238

Win10或Win8下ObjectARX2015 Wizard向导创建项目失败解决方法

[原创]objectARX 2015 Wizard安装向导在Win8/win10下无法创建项目的解决方法总结 by edata @2017-5-1 objectARX 2015 Wizard安装向导在Win8/win10下无法创建项目的解决方法 因为Win8/Win10对系统盘(默认c:)使用了高级权限管理,所以在此盘下操作文件的修改工作都需要管理员权限才行。 基于这个原因,导致非管理员安

edata的博客 7029

ZLogger:高性能零分配日志库

**NuGet 包**:[ZLogger NuGet](https://www.nuget.org/packages/ZLogger)

gitblog_00162的博客 1085

01-诊断开发流程概述

传送门 ==>> AutoSAR入门和实战系列总目录。

1786

简单两步使用Unity制作ZigZag游戏

原文链接:http://forum.china.unity3d.com/forum.php?mod=viewthread&tid=20816&extra=page%3D1%26filter%3Dtypeid%26typeid%3D18&ordertype=1 这个教程比较简单,算是入门级别的,但是挺好玩的,如图是我制作的效果

赖张殷-Eagle 1568

【Windows Server 2019】组策略的配置与管理——理论基础

博文介绍了组策略的定义,作用和分类。组策略包括计算机配置和用户配置;组策略又分为为基于本地的组策略和基于AD(活动目录)的域组策略。并说明了不同组策略发生冲突时默认的规则。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 1万+

[Dify实战] OA 公文排版助手:自动格式化、编号、生成摘要-带配套资源

摘要: Dify 公文排版助手通过自动化解决公文处理中的格式混乱、编号错漏等问题。支持标题层级自动编号、摘要生成、要素补全等功能,输出标准化Markdown格式。核心流程包括输入原文、智能识别、自动排版与要素输出,适用于通知、纪要等场景。实施需统一模板规则,规范输入格式,并通过试跑优化纠错率与处理效率。关键价值在于减少人工返工,提升排版一致性,未来可对接OA系统实现全流程自动化。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 472

ZLogger与Unity集成:游戏开发中的高性能日志解决方案

ZLogger是一款基于Microsoft.Extensions.Logging构建的零分配文本/结构化日志库,特别针对.NET平台优化,通过StringInterpolation和Source Generator技术实现高效日志处理。在游戏开发中,尤其是Unity项目,高性能日志解决方案至关重要,ZLogger与Unity的集成能够显著提升日志系统的性能和可靠性。 ## 为什么选择ZLogge

gitblog_00287的博客 437

ADS基础教程22 - 有限元电磁仿真(FEM)

一、引言二、FEM操作过程1.新建Layout1.新建Layout2.EM设置3.设置Frequency plan4.设置Output plan5.设置Options6.设置网格频率7.仿真结果三、总结介绍了在ADS中如何进行FEM仿真过程。END!}}END!

XZ_ZC的博客 2583

ZLogger最佳实践:从开发到部署的完整日志管理流程

ZLogger是一款基于Microsoft.Extensions.Logging构建的零分配文本/结构化日志库,专为.NET开发打造,通过StringInterpolation和Source Generator技术实现高效日志记录。本文将带您探索从开发配置到部署优化的完整日志管理流程,帮助您充分发挥ZLogger的性能优势。 ## 为什么选择ZLogger? 在现代应用开发中,日志系统的性能和

gitblog_00147的博客 450

华为OD机试真题 新系统 - 勇攀数字高峰 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 2096

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Utf8StringInterpolation 项目教程

Utf8StringInterpolation 项目教程 项目介绍 Utf8StringInterpolation 是一个专注于生成和写入 UTF-8 字符串的 C# 库。它利用 C# 编译器的特性进行自定义字符串插值,提供类似于 StringBuilder 的连续写入功能。该库是 ZString 的继任者,基于 UTF-8 编码,实现了零分配和高性能的字符串插值和 StringBuilder。 ...

gitblog_00485的博客 563

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

探索ZLogger:跨平台的远程持久键记录器

探索ZLogger:跨平台的远程持久键记录器 在数字时代的洪流中,监控与日志管理成为了保障系统安全、进行应用故障排查的重要工具之一。今天,我们要向大家推荐一个特别的技术解决方案——ZLogger,一款简洁而强大的远程持久键记录器,专为Windows和Linux两大操作系统设计。 项目介绍 ZLogger,正如其名,是一个专注于键盘活动跟踪的开源工具,它轻量级且功能高效,能够在无需root或管理员权...

gitblog_00006的博客 500

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Dialogic 2深度解析:构建专业级视觉小说游戏的全栈解决方案

Dialogic 2作为Godot引擎中功能最全面的对话系统框架,为游戏开发者提供了从角色管理到剧情编排的一站式创作平台。这个开源工具不仅简化了对话系统的实现流程,更通过模块化设计为视觉小说、RPG和互动叙事游戏提供了专业级的开发体验。无论你是独立开发者还是团队项目,Dialogic 2都能帮助你快速构建引人入胜的叙事体验。 ## 核心架构:模块化设计的对话引擎 Dialogic 2采用高度模

gitblog_00405的博客 415

ZLogger v2 架构:利用 .NET 8 最大限度地提高性能

这是一个用于 C# 和 .NET 的新的超快速和低分配日志记录库。它已从 v1 开始完全重新设计,以与最新的 C# 功能保持一致。虽然它最适合 .NET 8,但它支持 .NET Standard 2.0 及更高版本,以及 Unity 2022.2 及更高版本。.NET 和 Unity 版本都支持文本消息和结构化日志记录(默认为 JSON 和 MessagePack)。Cysharp/ZLogger...

dotNET跨平台 455

基于多线程的高性能异步日志管理机制与实现

通常在日志写的过程,每次写日志时,都是直接写入文件中。当数据量不大的时候,完成可以这样做,不会有什么问题。但是当数据量大时,每次写数据则会由于IO的瓶颈造成很大的性能问题。 为了解决这个问题,本文设计了一套基于多线程的在内存中追加日志后再写入文件的缓冲机制,从而解决这个问题。 基本原理 内存日志列表 首先建立一个缓冲列表用于保存日志。当日志在生成以后,先写入缓冲中,从而利用高速的内存可以以极高的...

郝伟老师的博客——大数据、并行计算与人工智能时代 1440

.net core 日志引擎 ILogger接口与使用

ILogger接口与使用 https://github.com/aspnet/Logging core 日志项目地址 1.配置IDE可调试core 源码 .net core源码都是开放的,配置的目的是为了调试的时候可以直接步进.core源码,方便查看框架内部实现方式。 效果 2.日志记录器简单使用 2.1 配置日志提供器 2.2 注入需要记录日志的...

猫妖九尾 2万+

.NET C# 高性能日志类

.NET C# 高性能日志类,主要采用队列的方式将需要写入的日志记录排队,由独立的线程完成异步写入。 这样可避免在阻塞调用日志类的线程。 下面贴出核心代码,希望大家共同讨论。   using System; using System.Collections.Generi

西蒙吹牛 4201

Qogir-theme支持哪些桌面环境?完整兼容性列表与配置技巧

Qogir-theme是一款采用扁平化设计的GTK主题,为Linux桌面环境提供现代简约的视觉体验。本文将详细介绍Qogir-theme支持的桌面环境兼容性列表及实用配置技巧,帮助用户快速部署和个性化这款主题。 ## 一、核心兼容性列表 🖥️ Qogir-theme通过模块化设计支持多种主流桌面环境,以下是经过验证的兼容环境: ### 1. GNOME Shell - **支持版本**:3

gitblog_01187的博客 533

ZLogger

ZLogger.hpp //z 2014-07-15 16:43:51 L.169'26169 BG57IV3@XCL T1740119909.K.F1752546504[T1,L73,R1,V21] #pragma once class ZLogger { public: //z gnu log level : DEBUG < INFO < WARN &lt...

214

完全掌握3D高斯泼溅技术:从零基础到高效渲染的完整实战指南

3D高斯泼溅技术正在革命性地改变计算机图形学领域,而**gsplat**作为这一前沿技术的开源实现,通过CUDA加速带来了前所未有的性能突破。无论你是计算机视觉新手还是经验丰富的开发者,本指南都将带你全面掌握**3D高斯泼溅**的核心原理和实战应用,让你能够快速上手并应用于实际项目中。 ## 🌟 核心理念:重新定义3D场景表示 ### 什么是3D高斯泼溅? 想象一下,传统3D渲染就像用乐高

gitblog_01068的博客 666
上一篇: Git 源码编译,冲突对比异常排查
下一篇: 打Tag傻瓜工具
ChiLi_Lin
博客等级 码龄12年 760粉丝 184原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值