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

推荐订阅源

SecWiki News
SecWiki News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 叶小钗
S
SegmentFault 最新的问题
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
量子位
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 三生石上(FineUI控件)
Attack and Defense Labs
Attack and Defense Labs
AI
AI
The Cloudflare Blog
T
Tailwind CSS Blog
S
Schneier on Security
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Stack Overflow Blog
Stack Overflow Blog
S
Secure Thoughts
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
S
Securelist
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
K
Kaspersky official blog
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Simon Willison's Weblog
Simon Willison's Weblog

博客园 - 幸福的菜菜

windows下使用ACME申请SSL证书的办法 ElementPlus Radio 实现双击取消选择的效果 Windows10 LTSC版本 无法访问网络中部分的共享文件夹 SqlSugar : date绑定到XX失败,可以试着换一个类型,或者使用ORM自定义类型实现 VisualStudio Debug模式突然变慢 Visual Stadio 编译提示 The BaseOutputPath/OutputPath property is not set for project ... node-sass编译不通过, 提示 “checking for Python executable "python2" in the PATH” c# async await的使用方式及为啥要用它 winform 实现对usb热拔插的监听 Laravel The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths Wampserver 配置端口可访问服务 git credential for windows 总是弹出的问题 如何用B表的数据,更新A表的值 WampServer部署https 服务的过程 PHP 命名空间冲突解决方式 Windows下 Docker 简单部署 Django应用 C#实现后台格式化U盘的功能 Winform 实现断点续传的思路及代码 WAMPServer ServerName has syntax error 的问题(阿里云服务器上)
winform绘图与前端canvas绘图效率对比
幸福的菜菜 · 2023-03-20 · via 博客园 - 幸福的菜菜

先说结论:前端canas的绘图效率更高。

因为项目使用winform的缘故,最近要实现一些波形展示的功能。涉及到绘制,肯定离不开GDI+的内容,但是还有替代的方案吗? 当然是有的,可双用WebView2使用前端的技术去绘制。

那么问题来了,哪一种实现更好呢?所以做了一些测试对比

以下是使用GDI+绘制的方式,使用了双缓存加速,绘制100W条线,速度大概是3.4s左右完全渲染出来

    public partial class DrawMaxPointTestForm : Form
    {
        public DrawMaxPointTestForm()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Task.Factory.StartNew(() =>
            {
                Random random = new Random();
                var pen = new Pen(Color.Black, 1);
                Stopwatch sw = new Stopwatch();
                sw.Start();

                var grap = this.CreateGraphics();
                var rect = new Rectangle(0, 0, this.Width, this.Height);
                using (BufferedGraphics bufferedGraphics = BufferedGraphicsManager.Current.Allocate(grap, rect))//创建缓冲 Graphics对象,区域
                {
                    bufferedGraphics.Graphics.Clear(Color.White);

                    List<float> widths = new List<float>();
                    List<float> heights = new List<float>();

                    List<PointF> points = new List<PointF>();
                    for (int i = 0; i < 1000000; i++)
                    {
                        points.Add(new PointF((float)(this.Width * random.NextDouble()), (float)(this.Height * random.NextDouble())));
                    }

                    bufferedGraphics.Graphics.DrawLines(pen, points.ToArray());

                    bufferedGraphics.Render(grap);
                }

                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds);
            });
        }
    }

那使用前端效率怎么样呢?

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <p>
        <button onclick="drawCanvas()">绘制图形</button>
    </p>
    <canvas id="drawCanvas" width="1500" height="1500"></canvas>


</body>

<script>

    function drawCanvas() {

        let bound = 1500;
        let canvasDom = document.getElementById("drawCanvas");
        let ctx = canvasDom.getContext("2d");

        ctx.clearRect(0, 0, bound, bound);

        let start = Date.now();
        let widths = [];
        let heights = [];
        ctx.beginPath();
        let x = 0;
        let y = 0;
        let maxCount = 100 * 10000;
        for (let i = 0; i < maxCount; i++) {

            x = Math.random() * bound;
            y = Math.random() * bound;

            ctx.lineTo(x, y);
        }
        ctx.lineWidth = 1;
        ctx.strokeStyle = "blue";
        ctx.stroke();
        ctx.closePath();
        console.log("time consume:", Date.now() - start);
    }

</script>

</html>

100W个点,在控制台输出显示只有

啥?81ms ? 这不可能,因为在界面上明显看到绘图有等待时间的,大约1s左右。

嘿嘿,这个就是chrome的线程优化相关的内容了。因为上面的计时只是把数据API丢给chrome后台去绘制,距离渲染完成还有些时间。即时这样,1s时间也是远超winform GDI+的效率的

但是上面是基于纯chrome测试的,要想把他集成到WebView2中还要考虑多个因素: 

  • 使用WebView2传值的性能损耗,100W个点,从c#传给前端会有性能损失吗?
  • WebView2版本与我所测试的chrome版本不同。(WebView2 所使用的chrome内核版本一定是低于我所测试的版本

如果实际项目应用中,上述两点还是需要测试一下。(虽然对性能影响会很小,不过还是要注意排坑)