我正在开发一个绘图应用程序,用户可以在该应用程序中创建和删除形状,并使用鼠标选择它们来拖动它们。所选形状应在“选择”数组中引用,还是每个形状都应具有isSelected属性?一种方法比另一种方法有什么好处吗?到目前为止,我注意到了这一点(我会用人们发现的任何东西来更新它)。我主要关心的是编程的简单性和性能。这个问题在很大程度上是独立于语言的,但应用程序是用javascript编写的,呈现是在html5画布上完成的。
检查选择状态
虽然我们立即知道如果一个项是通过布尔属性选择的,但是基于数组的解决方案需要遍历数组来搜索该项的引用。这种验证是非常常见的,因为当鼠标悬停选定的形状时,光标应该改变为“拖动”图标,或者当鼠标悬停在非选定的项目上时,会变成“指向手”图标。
取消选择项
使用布尔属性,选择和取消选择特定项是瞬时的。然而,对于数组选择,我们必须首先遍历所选内容,以便在添加或从所选内容中删除项目之前查看该项是否存在。这使得“切换选择”和“添加到选择”选项要慢得多。然而,在这样的绘图程序中,最常见的操作是在选择特定元素之前清除所选内容。使用数组方法,清除所选内容就像替换数组一样简单,而布尔方法要求在所有项上将isSelected属性设置为false。
删除项目
值得一提的是,在删除某项之前,必须将其从选择数组中删除。这个细节在isSelected方法中没有显示出来。
调用所有选定项
应用于所有选定项的操作需要最少的数组代码,因为我们只需遍历所选内容并对每个元素调用该方法。如果选择相对于项目的总数量来说很小,那么只需要通过选择来循环就可以获得相当长的时间增益。对于布尔属性,对所有选定项调用操作所需的时间取决于项目的总数,而不是选择的大小。
绘图时间
选定的项目通常有颜色的边框,可以通过其他元素看到。这意味着必须在所有其他元素前面绘制选择边界。给定项目"n“的数目和选定项目的数目(”s“).
数组解决方案从O(n)到2*O(n)呈现。
布尔解决方案需要使用2*O(n)来呈现。
虽然您可能认为这说明选择数组方法本身是合理的,但请记住,重绘只在操作被触发之后才完成,而不是每秒60次。检查尖头形状,以确定它是否被选中比绘图更常见。唯一可能明显慢下来的功能是拖动、拉伸和矩形选择。由于应用程序用于表示现实生活中的项目,人们通常在键盘上输入他们想要的大小,而不是实际拖动项目。
Encapsulation
封装使用布尔属性更强,因为条目知道它们是否被选中,而无需查看应用程序范围变量。这种差异在严格的范围内可能有很大的意义,但在javascript中并不是什么大问题。我想人们可能会认为,选择自己不是形状的角色。
发布于 2015-02-06 20:53:46
我已经实现了布尔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函数,以便在所有选定的元素上绘制蓝色边框!
当我发布这个问题时,我不确定这是否是过早的优化,现在我知道它不是。
使用数组跟踪选定项的主要缺点
使用每项布尔值跟踪选定项的主要缺点。
所以我已经决定了一个更好的方法来处理所有的消极方面:两者都做。我将在后台保留一个所选项目的数组,当选择和取消选择时,它将被更新。这样就消除了仅数组选择的所有坏方面,因为我不再需要搜索任何数组来确定是否选择了特定元素(我可以查看它的布尔值)。适用于选定项但不选择和取消选择项(例如移动、调整大小、绘制)的所有函数都可以通过选择数组循环。两个世界中最好的!
https://stackoverflow.com/questions/28326399
复制相似问题