在很多性能测试开始之前,都需要测试一下自己的期望优化的设备的性能上限是多少。我每次都是重新写一个测试应用,因为每次需要优化的方向都不相同。本文将记录一个我写的一个简单的测试应用,这里面包含了一千个半透明的矩形,且矩形都在做动画。可以测试自己的电脑的性能,看看是否一千个带动画的半透明矩形就带不动

本文的实现过程非新手友好,但是如果只是想测试一下性能,那只需获取代码跑起来即可,没有什么难度。到本文末尾可以获取全部的可构建运行的代码,按照本文提供的方式可以获取到所有源代码

开始之前,先看一下运行效果

接下来将告诉大家这个测试应用是如何做的

为了将关注点在于渲染性能或者是动画性能本身,减少其他业务逻辑的干扰,包括业务逻辑间接触发 WPF 的框架逻辑的干扰。比如修改布局层的属性,如元素的宽度高度等,导致布局系统重新布局,耗时在布局上,或者是布局触发的事件被业务监听,额外执行了业务逻辑。本次的测试应用将尽可能减少这部分的干扰,使用比较基础的方式编写

在 MainWindow 的 Loaded 事件里编写实现逻辑,如此可以规避 Win32 窗口创建时的故事,也方便大家进行性能测量

    public MainWindow()
{
InitializeComponent(); Loaded += MainWindow_Loaded;
} private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// 在这里编写代码
}

为了规避布局的干扰,这里决定作为一个画刷绘制到窗口的背景。如此将可以无视布局逻辑

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var drawingGroup = new DrawingGroup();
using (var drawingContext = drawingGroup.Open())
{
// 编写绘制逻辑
} var drawingBrush = new DrawingBrush();
drawingBrush.Drawing = drawingGroup; Background = drawingBrush;
}

获取到 DrawingContext 即可开始绘制带动画的半透明矩形。在 2d 渲染上,矩形是占用资源极低的。再配合纯色画刷,减少了其他类型的画刷带来的其他逻辑的性能影响。加上半透明,如此可以让整个图层的渲染压力极大

开始之前,先画一下底色,选用白色作为底色。绘制底色是为了让 DrawingBrush 不会因为尺寸和窗口的尺寸不匹配导致需要进行缩放

        using (var drawingContext = drawingGroup.Open())
{
drawingContext.DrawRectangle(Brushes.White, null, new Rect(0, 0, ActualWidth, ActualHeight));
}

接着设置将要绘制的矩形的尺寸,以及在循环里面绘制多少次

                    var size = new Size(100, 100);

                    for (int i = 0; i < 1000; i++)
{
// 添加绘制逻辑
}

在循环里面添加带动画的半透明矩形。添加矩形需要设置矩形的起点,以及动画的终点,如此界面才会比较复杂

                var startPoint = new Point(Random.Shared.Next((int) (ActualWidth - size.Width)),
Random.Shared.Next((int) (ActualHeight - size.Height)));
var endPoint = new Point(Random.Shared.Next((int) (ActualWidth - size.Width)),
Random.Shared.Next((int) (ActualHeight - size.Height)));

使用随机数生成矩形的起点和终点,不要超过画布的大小,如此将不会导致画布缩放

                var startPoint = new Point(Random.Shared.Next((int) (ActualWidth - size.Width)),
Random.Shared.Next((int) (ActualHeight - size.Height)));
var endPoint = new Point(Random.Shared.Next((int) (ActualWidth - size.Width)),
Random.Shared.Next((int) (ActualHeight - size.Height)));

接着添加随机的颜色的纯色画刷,采用随机颜色减少画刷被重复利用。创建纯色画刷本身不需要多少资源,请看 dotnet 读 WPF 源代码笔记 创建 SolidColorBrush 性能没有想象那么差

但是使用画刷是需要一些资源的

                var random = new byte[3];
Random.Shared.NextBytes(random);
var brush = new SolidColorBrush(Color.FromRgb(random[0], random[1], random[2]))
{
Opacity = Random.Shared.NextDouble()
};

再给画刷加上半透明,对于绘制来说,半透明和非半透明的性能差距是非常大的。因为半透明需要对背景进行采样,而背景又是其他的元素,自身由是其他的元素的背景,于是渲染需要的资源会非常大

接着继续添加动画

                IEasingFunction? easingFunction = Random.Shared.Next(10) switch
{
1 => new CubicEase(),
2 => new BounceEase(),
3 => new CircleEase(),
//4 => new ElasticEase(),
5 => new ExponentialEase(),
6 => new PowerEase(),
7 => new QuadraticEase(),
8 => new QuarticEase(),
9 => new SineEase(),
_ => null,
}; var rectAnimation = new RectAnimation(new Rect(startPoint, size), new Rect(endPoint, size),
new Duration(TimeSpan.FromSeconds(Random.Shared.Next(1, 100))))
{
RepeatBehavior = RepeatBehavior.Forever,
AutoReverse = true,
EasingFunction = easingFunction,
}; var animationClock = rectAnimation.CreateClock();

每个动画都是不相同的

将此矩形添加绘制

                drawingContext.DrawRectangle(brush, null, new Rect(startPoint, size), animationClock);

敲黑板,调用 DrawingContext 的各个方法,不是立即开启渲染,而是将渲染的指导数据写入到 WPF 框架。在 WPF 框架里面,将通过渲染调度逻辑将渲染的指导数据调度到 WPF 的 GFX 层。在 GFX 层再将具体的渲染指导数据写入到 DirectX 层,最后由 DirectX 层进行实际的渲染

以上就是所有的逻辑,可以尝试跑一下,看看在自己的机器上的效果

另外,再试试在 Debug 和 Release 下分别执行,以及调试下和非调试下执行的性能

本文的代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 3fdee3ab25c576016c2c756b3ec79cbe15158b72

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 3fdee3ab25c576016c2c756b3ec79cbe15158b72

获取代码之后,进入 JarqiwhaywherBuwailaryahefairha 文件夹

更多渲染相关,更多 WPF 底层相关,更多性能测试相关,请参阅 博客导航

WPF 一千个矩形做动画测试性能的更多相关文章

  1. [UWP]用Shape做动画(2):使用与扩展PointAnimation

    上一篇几乎都在说DoubleAnimation的应用,这篇说说PointAnimation. 1. 使用PointAnimation 使用PointAnimation可以让Shape变形,但实际上没看 ...

  2. [UWP]用Shape做动画

    相对于WPF/Silverlight,UWP的动画系统可以说有大幅提高,不过本文无意深入讨论这些动画API,本文将介绍使用Shape做一些进度.等待方面的动画,除此之外也会介绍一些相关技巧. 1. 使 ...

  3. WPF实现QQ群文件列表动画(二)

    上篇(WPF实现QQ群文件列表动画(一))介绍了WPF实现QQ群文件列表动画的大致思路,结合我之前讲过的WPF里ItemsControl的分组实现,实现起来问题不大,以下是效果图: 其实就是个List ...

  4. WPF实现QQ群文件列表动画(一)

    QQ群大家都用过,先看下目前QQ的群文件列表容器的效果: 细心点大家就会发现,这玩意收缩和展开是带动画的,并不是很僵硬地直接收缩或者直接展开,毫无疑问,如果用WPF实现这样的效果,这里的最佳控件是Ex ...

  5. WPF中的PathAnimation(路径动画)

    原文:WPF中的PathAnimation(路径动画) WPF中的PathAnimation(路径动画)                                                 ...

  6. canvas做动画

    一.绘制图片 ①加载图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  7. WPF重写Image实现动态图片--未测试

    WPF很强大,但是当WPF的image控件遇到gif时就只读了图片的第一帧,很好很强大! WPF不屑于gif的简单动画! 幸好WPF里有MediaElement这个东西,它是对MediaPlyer的一 ...

  8. (转)学习使用Jmeter做压力测试(三)--数据库测试

    数据库测试 JMeter可以做为Web服务器与浏览器之间的代理网关,以捕获浏览器的请求和Web服务器的响应,这样就可很容易的生成性能测试脚本. 根据脚本,JMeter可通过线程组来模拟真实用户对Web ...

  9. 使用requestAnimationFrame做动画效果二

    3月是个好日子,渐渐地开始忙起来了,我做事还是不够细心,加上感冒,没精神,今天差点又出事了,做过的事情还是要检查一遍才行,哎呀. 使用requestAnimationFrame做动画,我做了很久,终于 ...

  10. 使用uiautomator做UI测试

    转载~~~~~~~~~~~~~~~~~~~~~~~~ 若有侵权,请及时联系本博主,博主将第一时间撤销 在Android 4.1发布的时候包含了一种新的测试工具–uiautomator,uiautoma ...

随机推荐

  1. Tableau 绘制圆环图

    一.对应数据如下所示 二.打开tableau连接对应Excel数据源,将记录数字段连续拖动两次到行,显示设置按整个视图显示,标记里面设置按饼图显示 三.设置两个值按度量值平均值显示,并调整第一个图稍微 ...

  2. cadence软件画版图操作

    cadence软件操作 1.原理图设计 电路的原理图设计和许多的电路设计软件是类似的,这里大致介绍一下基本的操作. 首先是新建一个cell的原理图: library manager>file&g ...

  3. 初学STM32 CAN通信(一)

    # 初学STM32 CAN通信(一) 1. CAN协议简介 ​ CAN是控制器局域网络(Controller Area Network)的简称, 是国际上应用最广泛的现场总线之一 ,近年来,它具有的高 ...

  4. 【已解决】linux安装mysql依赖包(mysql-community-common-5.7.35-1.el7.x86_64)冲突

    错误信息: 软件包 mysql-community-common-5.7.35-1.el7.x86_64 (比 mysql-community-common-5.7.28-1.el7.x86_64 还 ...

  5. 使用OHOS SDK构建lua

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/lua/lua.git ...

  6. 深入探讨Java面试中内存泄漏:如何识别、预防和解决

    引言 在编写和维护Java应用程序时,内存泄漏是一个重要的问题,可能导致性能下降和不稳定性.本文将介绍内存泄漏的概念,为什么它在Java应用程序中如此重要,并明确本文的目标,即识别.预防和解决内存泄漏 ...

  7. OpenHarmony Camera源码分析

    一.简介 当前,开源在科技进步和产业发展中发挥着越来越重要的作用,OpenAtom OpenHarmony(简称"OpenHarmony")赋予了开发者孕育创新的种子,也为数字化产 ...

  8. 【Kotlin】类和对象

    1 前言 ​ Kotlin 是面向对象编程语言,与 Java 语言类似,都有类.对象.属性.构造函数.成员函数,都有封装.继承.多态三大特性,不同点如下. Java 有静态(static)代码块,Ko ...

  9. WPF/MVVM模式入门教程(二):实现INotifyPropertyChanged接口

    引用:https://www.cnblogs.com/flh1/p/12447188.html 1.创建NotifyPropertyChanged类 我们在common文件夹下创建一个名为Notify ...

  10. 「译文」深入了解Kubernetes和Nomad

    ️原文链接: https://www.cncf.io/blog/2023/10/23/introduction-a-closer-look-at-kubernetes-and-nomad/ ✍️作者: ...