Javascript在地图中查找键时会延迟

Javascript在地图中查找键时会延迟,javascript,Javascript,我有一个具有非常简单数据结构的实时应用程序:从一个时间(以秒为单位)到一个状态(我的系统状态)的映射。对于每一帧,我都会得到一个给定的时间,我想检索这个时间的状态 例如,如果我有3种状态: 0.3a->state_a 0.7->state_b 1.1->state_c 如果给定t=0.5,我应该返回状态_b,因为0.7是最小键,因此k>=t 下面是我的实现(用伪代码): 这段代码运行完美,速度相当快。问题是,在某些情况下它会中断。事实上,在JavaScript中,键总是字符串。因此,当我过滤

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

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

  • 0.3a->state_a
  • 0.7->state_b
  • 1.1->state_c
如果给定t=0.5,我应该返回状态_b,因为0.7是最小键,因此k>=t

下面是我的实现(用伪代码):

这段代码运行完美,速度相当快。问题是,在某些情况下它会中断。事实上,在JavaScript中,键总是字符串。因此,当我过滤它们并找到最小值时,我使用的是字母顺序,而不是数字顺序,然后我们得到19<2

我通过在程序启动时执行此操作来修复它:

keys = map(keys, parseFloat) //convert all keys to floats 
现在一切都很完美,但速度却慢得离谱(只需添加这行代码)

我试图找出它的来源,我的想法是:

  • 比较浮点值比比较字符串慢,根据我的基准测试,字符串比较为false(很抱歉,我无法发布它们,因为jsperf已关闭,并且它们的herokuapp似乎不起作用)
  • 使用浮点访问地图比使用字符串访问地图慢。根据我的基准测试,这是真的(nodejs慢17倍,而firefox39慢1.3倍)
你对这个问题怎么看

我是否错过了解决这个问题的简单方法


非常感谢

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

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


只要你有少于10亿个密钥,这就不应该是一个性能问题(更可能是内存问题而不是计算时间问题)。

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

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


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

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

问题来自:

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

所以有时候我想在这个例子中得到一个状态“1”。它在映射中不存在(而“1.00”作为键存在)。应用程序没有任何要渲染和跳过的帧,因此看起来很滞后。

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

问题来自:

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

所以有时候我想在这个例子中得到一个状态“1”。它在映射中不存在(而“1.00”作为键存在)。应用程序没有任何渲染和跳过帧的内容,因此看起来很滞后。

我通常同意@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

我大体上同意@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


我知道,但正如你在我的问题中看到的,问题是使用字符串访问地图。如果我照你说的做,我仍然会选择键作为浮点数,并且读取状态[selectedKey]仍然很慢。这并不能解决问题。确切地说,您正在对所有值运行一到两次。使用二进制搜索时,速度应该会小得多。速度慢的事情不会对所有值进行两次检查。否则,使用字符串作为键仍然会很慢。问题不是从数组中进行选择,这一点都不慢。你完全阅读了我的文章了吗?在我将键从string转换为floatsI之后,速度变慢了。我知道,但正如您在我的问题中看到的,问题是使用字符串访问地图。如果我照你说的做,我仍然会选择键作为浮点数,并且读取状态[selectedKey]仍然很慢。这并不能解决问题。确切地说,您正在对所有值运行一到两次。使用二进制搜索时,速度应该会小得多。速度慢的事情不会对所有值进行两次检查。否则,使用字符串作为键仍然会很慢。问题不是从数组中进行选择,这一点都不慢。你完全阅读了我的文章了吗?在我将键从string转换为float之后出现了减速,因为据我所知,这是我发现的唯一正确的解决方案,因为jantimon和cristies解决方案与我的解决方案一样糟糕:console.log(data[getClosestKey(data,504.3260)];“jantimon jsbinI中未定义的返回我同意所有关于二进制搜索的说法,但我的数组非常小(少于2000个)元素。做一个BS是没有意义的。代码会更复杂,更容易出错,而这看起来仍然落后。我只是因为你的最后一句话才发布了这篇文章。
我是否缺少一个简单的方法来解决这个问题?
=)快乐的编码!我只想说:“使用二进制搜索并不能解决问题。”“如果答案解决了你的问题,请随意接受。据我所知,这是我发现的唯一正确的解决方案,因为jantimon和cristies解决方案同样有效