我有一个非常简单的数据结构的实时应用程序:从时间(以秒为单位)到状态(我的系统状态)的映射。对于每一帧我得到一个给定的时间,我想要检索这个时间的状态。
例如,如果我有3个状态:
如果给出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
现在一切都很完美但是它非常缓慢(只需添加这行代码)
我试图找出它可能来自哪里,我的想法是:
您如何看待这个问题?
我错过了解决此问题的简单方法吗?
非常感谢
答案 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"
所以有时候我想得到一个州" 1"在这个例子中。它不存在于地图中(而#34; 1.00"作为关键字存在)。该应用程序没有任何渲染和跳过框架,因此它看起来滞后。
答案 2 :(得分:-1)
只做二进制搜索,它是O(logN),这是它的基本用例。
将所有keys
存储在已排序的数组中,然后您可以在X
中搜索值大于O(logN)
的最小键。
只要您有不到10亿个密钥,它就不应该是性能问题(更可能是内存问题而不是计算时间问题)。