优化

# 优化 > LeekScript 教程

这里我们讲优化,优化的目的是提高算法的性能。一般来说,当我们谈论优化时,我们谈论的是执行时间,目标是减少执行一系列指令所需的时间。

在 LeekScript 中,这个执行时间是由一个数字来估计的:这个计算使用的操作数。 因此,我们将讨论优化程序的某些良好实践和良好反应,无论使用何种语言,以及更特定于 LeekScript 的某些优化,并与计算操作的方式密切相关。

如果您还没有这样做,我邀请您阅读 LeekScript 教程 文章:Operations

良好的反应

例如,在只调用一次的函数上保存 500 次操作只会保存 500 次操作。 (逻辑) 另一方面,在循环的循环中调用的函数上节省单个操作可以减少数万个操作的操作成本。

这让我想到了第二点: ——认清哪里贵! 优化代码的一半工作只是简单地寻找操作离开的地方(然后你必须大声喊叫它们回来)。代码中有什么昂贵的?

为此,没有秘密,我们会衡量!

在我们的武器库中,LeekScript 提供了一个非常有用的函数:getOperations。 此函数允许了解到目前为止在代码中花费的操作数。

衡量功能成本的简单工具示例:

全局 __debug_operation; 函数 startOp(){ __debug_operation = getOperations(); } 函数 stopOp(标题){ 让 ops = getOperations()-__debug_operation - 3; debug("操作(" + title + "): " + ops); }

启动操作(); stopOp("空测试"); //空测试:0

启动操作(); 说(“你好世界”); stopOp("你好世界"); // 你好世界:30

因此,我们可以确认 say 花费了 30 次操作,正如文档中所宣布的那样。

这是可能的,我强烈建议你制作工具来衡量你的人工智能中的其他东西,比如调用一个函数的次数,以及它的平均成本,这将更好地衡量你的人工智能中成本的演变,以及某些优化的影响。

Complexity 页面将帮助您了解算法为何昂贵以及如何解决问题。非常简单地总结一下,我们更愿意尽可能避免它们之间的嵌套循环。我们还将寻求限制循环的大小,例如通过仅浏览我们可访问的单元格而不是浏览地图的所有单元格。 重要的是要注意,具有较低复杂性的算法将使用少得多更少的操作来处理足够多的项目,在尝试进行小优化之前请考虑一下!

删除不会改变的循环

想象一下下面的代码:

让 TP = getTP();

// 向敌人射击尽可能多的次数! for (var i = 0; i < floor(TP / getWeaponCost(getWeapon())); i++) { 使用武器(getNearestEnemy()); }

getNearestEnemy 函数将在循环的每次迭代中被调用,同时它总是返回相同的结果!为避免这种情况,只需将结果放在函数之前的变量中。 我们对 floor(TP / getWeaponCost(getWeapon())) 做同样的事情,它也在每次迭代中被评估。 哪个给:

让 TP = getTP();

// 向敌人射击尽可能多的次数! var enemy = getNearestEnemy(); var nbShots = floor(TP / getWeaponCost(getWeapon())); // 当前武器的可能射击次数 对于 (var i = 0; i < nbShots; i++) { 使用武器(敌人); }

昂贵的 Leek Wars 功能

inArrayinArray是实用的,它做了我们想要的,但是它涉及到一个显着的操作成本,我们乍一看不一定会注意到。 其实里面是这样的:

函数 inArray(元素,数组){ for(数组中的变量值) 如果(值==项目) 返回真; 返回假; }

这个例子很好地说明了一点复杂性。 我们在这里看到,这个函数的实际成本在最坏的情况下取决于数组数组的大小,我们将其命名为 n*。 因此这个函数有一个复杂度n*,它是