高效[JS?]算法列出并更新多个位置买入/卖出价格

时间:2018-03-09 20:59:28

标签: javascript vue.js vuetify.js

不,这不适用于面试问题,也不适用于密码! :)
这是一个个人非盈利的网络应用程序来补充游戏。

这个问题是部分财务,部分代码 我在Vue中编写这个Web应用程序,所以我更喜欢JavaScript解决方案,但抽象方法很好,伪代码会很棒,我应该能够将任何impl转换为JavaScript。

场景是这样的:
多个地点(例如:"商店")以不同价格买卖多件商品 价格随机变化(据说是供应/需求,但这是无关紧要的) 将有100-1000个位置和10-100个项目 大多数地方(估计80-90%)只会购买/出售一些物品 一些地点(估计1-10%)将购买/出售许多或所有物品 有些地方(估计有50%)可能只会买入或不卖出,或者只卖出而不买入。

我想要显示所有具有商品购买价格的所有地点的详尽清单,这些地点具有该商品的售价(类似于排列/组合,但有许多预期的差距)。 最终渲染的数据必须只是一个简单的对象列表/数组(键控/值)。

99M对象的分页列表(1000个商店*(1000-1)存储* 100个项目)将是最糟糕的情况,但预计数据中存在许多缺口,所以希望方式少于比1M对象(我希望不超过100,000;这些不必全部存在于内存中;我可以选择从存储中加载它们)

示例(按项目和购买位置排序以更好地查看示例数据集):
Item Buy Location Buy Price Ratio Sell Price Sell Location Item A Location A 4 0.5 2 Location B Item A Location A 4 2.0 8 Location C Item A Location B 6 0.66 4 Location A Item A Location B 6 1.33 8 Location C Item A Location C 10 0.4 4 Location A Item A Location C 10 0.2 2 Location B Item B Location A 3 0.33 1 Location B Item B Location A 3 1.33 4 Location C Item B Location B 3 0.66 2 Location A Item B Location B 3 1.33 4 Location C Item B Location C 5 0.4 2 Location A Item B Location C 5 0.2 1 Location B

列表中的每一列都是可排序的;默认排序将是"比率",它将显示购买和销售的最佳地点组合。 当任何价格更新时,Vue会自动更新列表并重新排序。

现在,我有关于如何做到这一点的想法,但它的效率非常低,因为我的解决方案是在任何单一价格变化时重新生成整个列表。
由于最终输出需要是可以任意排序的列表,因此没有真正的方法来索引或直接访问项目。
如果位置C的项目A购买价格的价格发生变化,则无法说明"更新第X行Y",甚至只更新行X"。 / p>

但是,我怀疑我错过了一些东西 我认为这是一项相当普遍的任务,之前已经以规模化的方式实施 示例:A"简单"在多个交易所买入/卖出价格图表 我曾考虑过查看开放式Crypto [Bot]代码,但这看起来更像是一个" Finance"我想要了解的问题,而不是我想复制的编码问题。

你会如何实现这个?
您会使用哪种数据集?

谢谢!

1 个答案:

答案 0 :(得分:1)

在我看来

  • 1M行数据太多,用户无法一次性读入。
  • 对于javascript来说,1M数组大小并不大(你可以在你的应用程序中检查大约10MB see how)但是将它全部呈现给DOM元素可能是一个非常大的问题。
  

你会如何实现这个?

所以在这种情况下,我将使用分页或聚合(例如每个项目的前10个最高比率)。

示例:

computed: {
  displayItems () {
    // This will update when one of rawItems, currentPage, pageSize updated
    return doFilterOrSort(rawItems).slice(currentPage * pageSize, pageSize)
  }
}

这将解决DOM元素过多的问题(如上所述,我假设更新1M数组的大小足够快,不会成为瓶颈)。

如果您的数据频繁变化,例如每秒10次。您可以通过限制或去抖来减少渲染时间来改善这一点。

限制示例:

watch: {
  rawItems () {
    if (!ticking) {
      requestAnimationFrame(() => {
        displayItems = doFilterOrSort(rawItems).slice(currentPage * pageSize, pageSize)
        ticking = false
      })
      ticking = true
    }
  }
}

如果您希望拥有无限滚动等行为,可以通过回收已经超出屏幕的DOM元素来实现。请参阅react-virtualized中的示例。

  

您会使用哪种数据集?

您没有告诉您检索的数据格式(初始和每次更新;按商店?按项目?),因此很难回答。

我假设商店和商品的数量是固定的(不经常更新),每次更新都是针对商店中的商品。表示 n m 表示商店和商品的数量。

我将使用3个数组:

第一个用于保持每个商店中每件商品的买/卖价值的数组。您可以在 O(1)

中轻松更新

每个项目的商店的每个组合保持比例对象的第二个数组,如:

[
  [aa, ab, ac],
  [ba, bb, bc],
  [ca, cb, cc]
]

// 3 stores, 1 item, each element is { r, a, b }
// r for ratio, a buy store, b sell store

您可以使用 O(n⋅n)进行更新,例如更新a:循环1到n,i = 2更新 ab ba

用于保持同一对象的第三个数组,以及以前的奉承或分组。排序或分组这将花费 O((n⋅n⋅m)log(n⋅n⋅m))(是的,这是你需要注意的瓶颈,方法取决于你的阵列形状)。

在更大的范围内(或者上面的所有内容都没有帮助,对不起)我认为不是将所有数据发送到客户端,而是应该在服务器中聚合它然后通过Web套接字发送它。

相关问题