首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我使用requestAnimationFrame + that图像的简单画布大约占cpu的8-9%,这是正常的吗?

我使用requestAnimationFrame + that图像的简单画布大约占cpu的8-9%,这是正常的吗?
EN

Stack Overflow用户
提问于 2016-10-01 15:32:16
回答 1查看 266关注 0票数 0

我正在用一个简单的例子测试HTML5画布,以绘制一些等距瓷砖。我使用的是requestAnimationFrame方法。然而,我可以看到大约8%的CPU使用在Chrome任务管理器中。

PS:我在使用Typescript

这是我的抽签循环:

代码语言:javascript
复制
private Draw = () => {
        this.Context.clearRect(0, 0, this.Canvas.width, this.Canvas.height);
        this.Context.imageSmoothingEnabled = false;
        this.DrawCtx();
        requestAnimationFrame(this.Draw);
}

DrawCtx用这个函数调用另一个类:

代码语言:javascript
复制
public Draw(MousePosition: Array<number>, ClickPosition: any): void {
        this.MousePosition = MousePosition;
        this.ClickPosition = ClickPosition;

        this.DrawBackground();
        this.ParseMap();
        this.Container.Draw();
        this.DrawTiles();
}

下面是drawTiles的一个片段(其他东西只是地图数组的一些for() )

代码语言:javascript
复制
if(!curtile.isDoor && typeof(this.Map.getMap().data[x - 1]) != "undefined" && this.Map.getMap().data[x - 1][y].height != 0 && this.Map.getMap().data[x - 1][y].height == (parseInt(curtile.height) + 1)) {
                            this.Container.drawImage(x + y + 500, this.Resources["1.png"], curtile.left, curtile.top - 24 - ((curtile.height - 1) * 6), 64, 64);
                        } else if(!curtile.isDoor && typeof(this.Map.getMap().data[x][y - 1]) != "undefined" && this.Map.getMap().data[x][y - 1].height != 0 && this.Map.getMap().data[x][y - 1].height == (parseInt(curtile.height) + 1)) {
                            this.Container.drawImage(x + y + 500, this.Resources["2.png"], curtile.left, curtile.top - 24 - ((curtile.height - 1) * 6), 64, 64);
                        } else if(!curtile.isDoor && ((typeof(this.Map.getMap().data[x][y - 1]) != "undefined" && this.Map.getMap().data[x][y - 1].height != 0 && this.Map.getMap().data[x][y - 1].height == curtile.height) || typeof(this.Map.getMap().data[x - 1][y]) != "undefined" && this.Map.getMap().data[x - 1][y].height != 0 && this.Map.getMap().data[x - 1][y].height == curtile.height) && typeof(this.Map.getMap().data[x - 1][y - 1]) != "undefined" && this.Map.getMap().data[x - 1][y - 1].height != 0 && this.Map.getMap().data[x - 1][y - 1].height == (parseInt(curtile.height) + 1)) {
                            this.Container.drawImage(x + y + 500, this.Resources["3.png"], curtile.left, curtile.top - 24 - ((curtile.height - 1) * 6), 64, 64);
                        } else {
                            this.Container.drawImage(x + y + 500, this.Resources["tile.png"], curtile.left, curtile.top - ((curtile.height - 1) * 6), Config.Game.TileWidth, Config.Game.TileHeight);
                        }

this.Container是我的drawImage指标体系

代码语言:javascript
复制
export default class Container {
    Objects: any = [];
    Context: any;

    constructor(Context: any) {
        this.Context = Context;
    }

    public drawImage(index: number, ...drawArguments: any[]) {
        this.Objects.push({
            index: index,
            args: drawArguments
        });
    }

    public Draw(): void {
        this.Objects.sort(function(a: any, b: any) {
            return (a.index > b.index) ? 1 : ((b.index > a.index) ? -1 : 0);
        });

        for(var i in this.Objects) {
            var object = this.Objects[i];
            this.Context.drawImage.apply(this.Context, object.args);
        }

        this.Objects = [];
    }
}

为什么它只为一些drawImages使用~8-9%的CPU?我的密码怎么了?还是很正常?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-02 00:11:28

对于速度,一般规则是“在可用的最低级别上写”:类型记录增加了开销,在Javascript中编写需要速度的代码。

不使用(在?)使用标准循环迭代,速度更快。

不要使用apply,直接调用该函数,这是一个好的6倍的速度(更多的Chrome)。注意,这是用于调用操作,而不是调用函数中的代码。

每次调用绘图时,都会创建和销毁一个新数组。这将产生重大影响。重用对象,永远不要取消性能循环中的任何内容。即使必须取消对数组中放置的所有新对象的引用,也不要在绘制函数的末尾创建一个新对象。重新设置它的长度。'objects.length = 0‘不会产生构造新数组对象的开销。

代码语言:javascript
复制
var currentObjectCount = 0;
var objects = [];

function drawImage(index,...etc)
    var o = objects[currentObjectCount];
    if(o === undefined){
       objects[currentObjectCount] = o = {};
    }
    o.index = index;
    o.args = etc;
    currentObjectCount += 1;
}

在添加对象集currentObjectCount = 0之前,在每个帧的开头

在呈现循环(绘制函数)中,使用currentObjectCount来修剪排序的数组

代码语言:javascript
复制
objects.length = currentObjectCount;

但是,如果您可以去掉排序,那么就不要修剪数组,在for循环中使用currentObjectCount。忽略当前框架不需要的任何对象。在数组中拥有额外的未使用的项目不需要花费任何费用,在需要时重用旧的项目不需要任何费用,取消引用需要花费成本,构建成本也不高。

你必须真正排序,任何类型的预排序,你可以做,将改进排序。在drawImage调用中使用插入排序,这只是一个简单的排序,它可以进行粗略的排序,从而使真正的排序更快。

但是对于呈现,您只需要在有重叠的情况下排序,如果您在任何阶段进行对象之间的距离或冲突测试,请使用该数据优化排序,保留两个对象数组,一个用于排序,另一个用于未排序。(35年来,我已经写了100部2D游戏,我从未在主渲染循环中使用过一种类型,一直有更好的方法。)

除掉传送带操作员。它很慢,而且绘制图像的变体不多,因此值得使用...进行开销。

飞吻是快速代码使用的规则。保持简单(第二个S是使首字母缩写)。保持简单并不意味着从表面上看您的代码是什么,而是简单到核心。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39808380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档