我正在使用一个绘图应用程序,用户可以在其中创建和删除形状,并使用鼠标选择它们以将其拖动。应该在“选择”数组中引用选定的形状,还是应该每个形状都具有isSelected属性?一种方法比另一种方法有什么优势吗?这是我到目前为止注意到的(我将使用人们发现的任何东西对其进行更新)。我主要关心的是编程的简单性和性能。这个问题在大多数情况下是与语言无关的,但是应用程序使用的是javascript,并且渲染是在html5画布上完成的。
检查选择状态
虽然我们可以立即知道是否通过boolean属性选择了某个项目,但是基于数组的解决方案需要遍历数组以搜索该项目的引用。考虑到鼠标将鼠标悬停在选定的形状上时光标应变为“拖动”图标,或将鼠标悬停在未选择的项目上时光标将变为“指向手”图标,因此这种验证非常普遍。
取消选择项目
选择和取消选择特定项目是通过boolean属性即时完成的。但是,对于array-selection,我们必须先遍历选择项以查看该项是否存在,然后再将其从选择项中删除。这会使“切换选择”和“添加到选择”选项变慢。但是,这种绘图程序中最常见的动作是在选择特定元素之前清除选择。使用array方法,清除选择就像替换数组一样简单,而boolean方法则需要将所有项目的isSelected属性设置为false。
删除项目
值得一提的是,在删除项目之前,必须从选择数组中删除该项目。这个细节不会在isSelected方法中显示。
调用所有选定的项目
适用于所有选定项目的动作只需要一个带有数组的最少代码,因为我们只需要遍历选择并在每个元素上调用方法即可。如果选择项与项目总数相比很小,则仅循环执行选择项就可以节省大量时间。使用布尔属性,对所有选定项目调用操作所需的时间取决于项目的总数,而不是选择的大小。
绘图时间
所选项目通常具有彩色边框,可以通过其他元素看到。这意味着选择边框必须在所有其他元素的前面绘制。给定项目数“ n”和所选项目数(“ s”)...
阵列解决方案利用从O(n)
到2*O(n)
渲染。
布尔值解决方案即将2*O(n)
呈现。
尽管您可能认为这样做证明自己选择使用数组方法是合理的,但请记住,重绘仅在触发动作后才执行,而不是每秒60次。检查指向的形状以了解是否已选中它比绘制图形更常见。可能会明显减慢的唯一功能是拖动,拉伸和选择矩形。由于该应用程序用于表示现实生活中的物品,因此人们通常在键盘上输入他们想要的大小,而不是实际拖动物品。
封装形式
布尔值属性使封装更强大,因为项无需知道应用程序作用域变量即可知道是否选择了它们。在严格范围的环境中,这种差异可能意味着很多,但是在javascript中并没有什么大不了的。我想人们可能认为选择自己不是形状的角色。
我已经实现了boolean isSelected属性,并且随着应用程序的发展,我构建了越来越多的应用于所有元素的函数。在每个函数中,我必须放置一个for循环,以确保仅更改选定的项目。我将编写某种伪代码来再次保持该解决方案语言的不可知性。
for each item {
if item is selected
do stuff
}
到处都有相同的循环让我很烦,这感觉很不对劲。当您在函数之间复制粘贴代码部分时,这绝不是一个好兆头。因此,我做了一个getSelection()函数,该函数返回了所选元素的数组。这似乎通过提取可怕的循环解决了我之前遇到的问题。
function getSelection() {
selection = new empty array
for each item in selection {
if item is selected
add item to selection array
}
return selection
}
function doStuffOnSelection() {
selection = getSelection()
for each item in selection {
do stuff
}
}
但这仅显示出更糟的事情。操纵数组(不断将项目推入数组,创建数组等)比仅浏览它们要慢得多。这项更改使应用程序的运行速度大大降低,以至于在Firefox中,我什至一次不能拥有100个项目,而以前曾经可以不掉帧地拥有2000个项目。之所以这么慢,是因为我现在创建了一个数组。这是因为需要在程序的每一帧上调用getSelection函数,以在所有选定元素上绘制蓝色边框!
当我发布此问题时,我不确定这是否为过早的优化,现在我知道不是。
使用数组跟踪选定项的主要缺点
-您需要查看所有选定的元素以确定是否选择了特定元素并更改该状态。
-要从所有元素的数组中删除选定的元素,您需要进行数组研究,当任一数组很大时,这特别慢。
使用每个项目的布尔值跟踪所选项目的主要缺点
-您需要查看所有元素以了解选择了哪些元素并更改该状态。
因此,我已经确定了一种更好的方法来应对所有不利方面:两者都做。我会继续在后台运行,当选择的东西,然后再取消它获取更新所选项目的数组。这消除了纯数组选择的所有弊端,因为我不再需要搜索任何数组来知道是否选择了特定元素(我可以查看其布尔值)。所有适用于选定项目但不选择和取消选定项目的功能(例如移动,调整大小,绘制)都可以在选择数组中循环。两全其美的!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句