【问题标题】:Fast access to data without using a database?不使用数据库快速访问数据?
【发布时间】:2013-05-16 06:56:38
【问题描述】:

我正在寻找一种快速访问一些缓冲数据的解决方案:

我有一堆(假设最多 200 个)缓存的位置信息,包括纬度和经度以及一些附加信息。现在我想(非常频繁地)比较我当前的位置并从这个缓存列表中找到最接近当前位置的位置。对所有缓存位置进行距离计算以找到最近的位置是消耗资源的事情,我希望避免这样做。

此外,还需要有可能将新位置添加到缓存列表并删除旧位置 - 但这是一件容易的事情,因为它对时间要求不高,而且很少做。

所以有什么想法吗?如何尽可能高效地评估缓存位置列表中最近的位置?

谢谢!

【问题讨论】:

  • 为什么不能为此使用数据库? SQLite 将能够非常快地做到这一点

标签: java android geolocation latitude-longitude


【解决方案1】:

我真的认为您应该为此使用 SQLite,尤其是在性能对您很重要的情况下。它不必很复杂,您只需要一个带有标记的简单表格

CREATE TABLE markers(_id INTEGER PRIMARY KEY, lat REAL, lon REAL);

先填表

BEGIN TRANSACTION;
INSERT INTO markers VALUES (NULL,lat1,lon2);
....
INSERT INTO markers VALUES (NULL,lat200,lon200);
COMMIT;

然后一个简单的查询就可以找到最接近位置 (x,y) 的标记

SELECT * FROM markers ORDER BY (x-lat)*(x-lat)+(y-lon)*(y-lon) LIMIT 1;

ORDER BY 中不需要平方根,因为 sqrt 是一个单调函数。

【讨论】:

  • “SELECT ... LIMIT 1”这个东西看起来又瘦又小,但在我看来不是!数据库在内部做什么?我想它必须以一种通用的方式做同样的事情,就像我可以更快地使用专门的代码一样:计算与 每个 存储位置的差异,只是为了找到最接近的一个。
  • @LuckyMe 完全是写出来的,我可以保证你不会比这个查询更快地编写任何代码,我怀疑很多人都可以。为什么不尝试编写代码以查看此查询需要多少时间?你会惊喜的;-)
【解决方案2】:

如果您想避免使用SQLite DB,我认为您可以这样做的唯一方法是将您的位置保存到文件 (text file/xml file) 并在访问您的应用程序时将此文件解析为内存中的结构比如List/ArrayList

您必须在每次访问您的应用程序时检查此结构是否为空,如果为空,则再次对其进行解析。

【讨论】:

  • 这样的解决方案的优势在哪里?为了找到最近的位置,将进行相同的计算,并加上一些额外的资源来解析 SQL 语句、访问接口、从磁盘检索数据。
  • 相比什么优势?你说你不想使用 SQLite DB,这将是它之后的最佳选择。您对需要时间的解析时间和磁盘访问是正确的。但最终你将不得不以某种方式存储数据。你不能把它留在记忆中。
【解决方案3】:

创建文件并访问它与 SQL 相同,差异如此之小以至于无关紧要,因为它们都在访问“硬盘”(在 Mobile 中,存储空间),因此延迟相同。

我喜欢 SQLite 数据库的想法,因为您可以使用一条语句检查整个表以获得正确的答案(您只需正确构造语句即可)。请记住,SQL 是一种极其智能和高效的数据库存储类型,从“磁盘”(表)缓存的数据会一直缓存,直到需要空间为止。

但是,如果您愿意,您可以读取该表一次,将其放入内存(一些全局可访问的变量),然后从那里继续。

PS:我会说重新考虑 SQLite DB 并为您的应用程序做一些测试时间并查看结果。 让我知道发生了什么,我很感兴趣。

【讨论】:

  • 我认为 Elmi 对缓存的意思是内存中的缓存,其访问时间远低于访问磁盘的时间。
  • Opps,一定错过了那部分,Emil 是正确的,除非你想使用共享首选项 (developer.android.com/guide/topics/data/data-storage.html#pref)。 Elmi,你的术语不准确,任何数据存储都被认为是数据库,所以你是指“不使用数据库访问数据”的 SQL 吗?
  • @LuckyMe,OP 想要一种在不使用数据库的情况下使用他的位置数据的方法(我认为这是内置 SQLite DB 选项)。因此,下一个最佳选择是为此使用文件。 OP 不能将位置数据留在内存中,因为如果用户离开应用程序一段时间,GC 可能会删除这些数据。我不知道将 200 个条目(OP 需要什么)保存到 SharedPreferences 中的方法。
  • @Emil Adz,什么是 OP 和 GC?可以系统地保存到 SharedPreferences 中。但同样,我和你在一起,我会订购它们:SQL > File > SharedPreferences。肯定有 SQL 的推荐。
  • OP - meta.stackexchange.com/questions/146513/what-does-op-mean GC - 垃圾收集器。如果您能向我介绍一种在 SharedPreferences 中保存 200 个条目的方法,我将非常高兴。我同意您的订单,但 OP 专门要求提供没有数据库的解决方案,因此这是下一个最佳选择。
【解决方案4】:

如果您不想使用数据库,请考虑使用某种形式的Binary Space Partitioning 树将数据存储在内存中。如果您只对 2D 空间感兴趣,那么Quadtree 就可以了。与简单的线性搜索相比,这可以显着降低搜索的复杂性,并且可以很好地应对人口稀少的区域(例如,如果很多点聚集在特定区域,彼此相距很远)。

还有其他 BSP 树可能更高效,但通常更难实现和调试。您可能希望找到一个库来省去从头开始编写数据结构的麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 2010-09-05
    • 2020-10-19
    • 1970-01-01
    相关资源
    最近更新 更多