Javascript奇怪的是在地图中找到一把钥匙

时间:2015-07-10 13:20:56

标签: javascript

我有一个非常简单的数据结构的实时应用程序:从时间(以秒为单位)到状态(我的系统状态)的映射。对于每一帧我得到一个给定的时间,我想要检索这个时间的状态。

例如,如果我有3个状态:

  • 0.3a - > STATE_A
  • 0.7 - > STATE_B
  • 1.1 - > state_c

如果给出t = 0.5,我应该返回state_b,因为0.7是最小键,因此k> = t

现在这是我的实现(伪代码):

var states // my map [time -> state]
var t // the time
var keys = keysOf(states) // get the key set of the states
var correctKeys = filter(keys, (k) -> k >= t) // removes all keys less than t
var selectedKey = min(correctKeys) // the best key
return states[selectedKey] // return the state we want to render

这段代码完美无缺。在某些情况下它会破坏的问题。事实上,JavaScript中的键始终是字符串。因此,当我过滤它们并找到最小值时,我使用的是字母顺序,而不是数字顺序,然后我们有19< 2

我通过在程序启动时执行来修复它

keys = map(keys, parseFloat) //convert all keys to floats 

现在一切都很完美但是它非常缓慢(只需添加这行代码)

我试图找出它可能来自哪里,我的想法是:

  • 比较浮点数比根据我的基准比较错误的字符串更慢(抱歉我不能发布它们因为jsperf已关闭而且他们的herokuapp似乎不起作用)< / LI>
  • 使用float访问地图比使用字符串访问地图要慢。 根据我的基准测试,这是真的(在nodejs上慢17倍,但在firefox 39上只有1.3倍)

您如何看待这个问题?

我错过了解决此问题的简单方法吗?

非常感谢

3 个答案:

答案 0 :(得分:1)

我普遍同意@jantimon和@Cristy,如果你关心性能,二进制搜索要好得多,因为你总是有O(n)的复杂性。

我刚注意到,只需对代码进行少量更改,就可以轻松解决问题,并且不需要将密钥转换为浮点数。

var a = '19';
var b = '2';

console.log(b >= a); // TRUE - as it compares strings
console.log(b - a >=0); // FALSE - as it compares ints / floats

答案 1 :(得分:0)

我找到了解决方案。事实上,使用浮动键作为键而不是字符串并不慢,它明显慢。让我解释。在每一帧我渲染程序的状态。它看起来很迟钝,但实际上并非如此。

问题来自:

parseFloat("1.00").toString() != "1.00"

所以有时候我想得到一个州&#34; 1&#34;在这个例子中。它不存在于地图中(而#34; 1.00&#34;作为关键字存在)。该应用程序没有任何渲染和跳过框架,因此它看起来滞后。

答案 2 :(得分:-1)

只做二进制搜索,它是O(logN),这是它的基本用例。

将所有keys存储在已排序的数组中,然后您可以在X中搜索值大于O(logN)的最小键。

只要您有不到10亿个密钥,它就不应该是性能问题(更可能是内存问题而不是计算时间问题)。