什么';用JavaScript编写时间戳-值对时间线的有效方法是什么?

什么';用JavaScript编写时间戳-值对时间线的有效方法是什么?,javascript,momentjs,Javascript,Momentjs,我正在编写一些代码,其中一个值可以随时间变化,我需要跟踪该值随时间的变化,以便能够获得任何时间戳的最新值。我正在使用Moment.js进行时间戳操作 我正在优化一种情况,通常情况下,值对不会在数十万个时间戳内改变,或者很少改变,但我仍然需要知道它是否改变/何时改变,以及最近在任何时间点的变化。最早记录对之前的时间戳查询应返回false class Timeline { constructor() { this.valuePairs = [] } setVa

我正在编写一些代码,其中一个值可以随时间变化,我需要跟踪该值随时间的变化,以便能够获得任何时间戳的最新值。我正在使用Moment.js进行时间戳操作

我正在优化一种情况,通常情况下,值对不会在数十万个时间戳内改变,或者很少改变,但我仍然需要知道它是否改变/何时改变,以及最近在任何时间点的变化。最早记录对之前的时间戳查询应返回false

class Timeline {
    constructor() {
        this.valuePairs = []
    }
    setValueAt(value, timestamp) {
        this.valuePairs.push({ timestamp, value })
    }
    getValueAt(timestamp) {

        // obviously I could iterate through this.valuePairs brute force, get 
        // the difference between each value-pair's timestamp and the target 
        // timestamp, returning the value with the smallest difference, but I 
        // feel bad about even writing this code, it's incredibly 
        // inefficient, and for big datasets, this would create a massive 
        // array to search through and take up memory

        let earliest = Infinity
        let closest = {
            value: false,
            difference: Infinity,
        }
        for (let i = 0; i < this.valuePairs.length; i++) {
            let valuePair = this.valuePairs[i]
            let difference = timestamp - valuePair.timestamp
            if (valuePair.timestamp < earliest) earliest = valuePair.timestamp
            if (difference < closest.difference) {
                closest.difference = difference
                closest.value = value
            }
        }
        if (closest.value && timestamp > earliest) {
            closest.value
        } else {
            return value
        }
    }
}
课程时间表{
构造函数(){
this.valuePairs=[]
}
setValueAt(值、时间戳){
this.valuePairs.push({timestamp,value})
}
getValueAt(时间戳){
//很明显,我可以重复这个。暴力,获取
//每个值对的时间戳与目标之间的差异
//timestamp,返回差异最小的值,但I
//即使是写这段代码也会感到很难过,这是难以置信的
//效率低下,而且对于大型数据集来说,这将造成巨大的损失
//要搜索并占用内存的数组
设最早=无穷大
让最近的={
值:false,
差异:无限,
}
for(设i=0;i最早){
最近值
}否则{
返回值
}
}
}

这是如此低效,以至于它基本上会使任何处理大批量数据的程序崩溃。但老实说,我想不出一个好办法。写这门课有什么更有效的方法?

试试看怎么样?当发生变化时,发出一个可观察的信号。如果这些观察值在代码中是相关的,那么设置订阅“侦听”相关更改。而且,因为您只对最新的修改感兴趣,所以我认为
行为主体
将是一个不错的选择。

试一试如何?当发生变化时,发出一个可观察的信号。如果这些观察值在代码中是相关的,那么设置订阅“侦听”相关更改。而且,因为您只对最新的修改感兴趣,所以我认为
行为主体
将是一个不错的选择。

我认为您可以使用它来提高程序的效率。要使用
Trie树
,您应该将
时间戳
转换为
日期
小时
分钟
毫秒
。并且每个元素表示
Trie树中的一个节点,如下所示。搜索
时间戳
以查找其值时,可以在
Trie树
中查找与
时间戳
具有相同
的节点,然后是相同的
,依此类推。如果没有一个节点具有与时间戳相同的
年份
,则应查找最近的邻居。该算法具有恒定的时间复杂度。在最坏的情况下,您应该每毫秒比较一次,并找到最接近的值,这将花费O(1000)个时间。

我认为您可以使用它来提高程序的效率。要使用
Trie树
,您应该将
时间戳
转换为
日期
小时
分钟
毫秒
。并且每个元素表示
Trie树中的一个节点,如下所示。搜索
时间戳
以查找其值时,可以在
Trie树
中查找与
时间戳
具有相同
的节点,然后是相同的
,依此类推。如果没有一个节点具有与时间戳相同的
年份
,则应查找最近的邻居。该算法具有恒定的时间复杂度。在最坏的情况下,您应该每毫秒比较一次,并找到最接近的值,这将花费O(1000)个时间。

我们说的是多大?数据集是经过排序的,对吗?所以只要使用@Bergi,这些就是更有效的暴力搜索,不是吗?Smart brute force lol。请看顶部的编辑,因为我正在为数据几乎从未实际更改的场景进行优化,我觉得应该有一种比插值搜索更有意义的替代方法。我想我也不需要跟踪每个时间戳,而是跟踪时间范围。@Bergi见编辑,澄清。只有数十万个时间戳条目。但是可能有10万条不同的时间线,每一条都更新了几十万次。嗯,是的,你只会在时间戳值发生变化的地方存储时间戳值对?你的数据来自哪里?它是否包含大量重复值?我们谈论的是多大?数据集是经过排序的,对吗?所以只要使用@Bergi,这些就是更有效的暴力搜索,不是吗?Smart brute force lol。请看顶部的编辑,因为我正在为数据几乎从未实际更改的场景进行优化,我觉得应该有一种比插值搜索更有意义的替代方法。我想我也不需要跟踪每个时间戳,而是跟踪时间范围。@Bergi见编辑,澄清。只有数十万个时间戳条目。但可能有10万条不同的时间线,每一条都更新了几十万次。嗯,是的,哟