java - 使用缓存对对象的 ArrayList 进行排序
问题描述
任何关于以下问题的建议将不胜感激。
现状:我有一个对象的ArrayList。我们已经使用比较器实现了排序。该对象有数百个字段。所以 ArrayList 中单个对象的大小并不小。展望未来,当 ArrayList 的大小增加时,由于 ArrayList 的整体大小,我们觉得这会在排序中产生问题。
计划:我们将在缓存中加载对象。我们计划不将对象的 ArrayList 作为输入,而是将 id(字符串)的 ArrayList 作为输入。当比较一个 id 时,我们计划从缓存中获取对象。
问题:我不想加载缓存中的所有对象,因为此缓存仅在排序期间使用。所以我不想为此创建一个巨大的缓存。
我打算做的是仅加载缓存中的一半对象,如果缓存中不存在任何内容,则从数据库加载它并读取它并将其放入缓存中(这将替换缓存中的一个对象)。我不想在数据库中查询单个对象,因为这样我会数万次访问数据库。
我想从数据库中批量读取,但我无法制定策略。
任何建议将不胜感激。
解决方案
你很困惑。
该对象有数百个字段。
无关紧要。Java 使用引用;您拥有的“对象数组列表”由一个数组支持,并且该数组中的每个插槽大约需要 8 个字节(取决于底层 VM 详细信息,也可能是 4 个字节)。这些或多或少代表了对象所在的内存位置。
当 ArrayList 的大小增加时继续前进
....不,它不会。如果您在此列表中放入 100,000 个条目,那么至少对于列表本身而言,这是一个总内存负载,最多为 800,000 字节,这还不到 1 兆字节。这么说吧:在现代硬件上,仅该列表就可以包含 1 亿个项目,您的系统不会出汗(用于引用的内存少于 GB)。现在,如果您也有 1 亿个唯一对象(例如,添加完全相同的对象 1 亿次,或者添加 null 1 亿次),那么该对象也会占用内存。那可能是个问题。但该列表不是相关部分。
由于 ArrayList 的整体大小,我们觉得这会在排序中产生问题。
不。当你对一个数组列表进行排序时,你会得到 ~nlogn 操作来对它进行排序。实际的排序基础设施部分(在列表中移动对象)足够接近零成本(它只是在单个内存页面上将那些 4 到 8 个字节序列传输。假设 .compare() 的调用很便宜,甚至是一次性的100 美元的计算机可以在几分之一秒内对数百万个条目进行排序。这只会留下 .compare() 的 ~nlogn 调用。如果这很昂贵,好吧,你可能有问题。所以,在 100 万个条目的列表中,你是查看您的 compare 方法的大约 1300 万次调用。
它有多快?
如果调用 .compare(a, b) (其中 a 和 b 是指向“数百个字段”对象实例的指针)检查这数百个字段中的每一个,这可能会有点棘手,但如果它只是检查其中一些,这里没有什么可担心的。CPU速度很快。你可能会说:“百万?我的天哪!”,但你的 CPU 会嘲笑这项工作。
我们将在缓存中加载对象。
由于以上原因,这个计划很糟糕。
我想从数据库中批量读取
好的,所以当您开始使用“我们有一个对象数组列表”时,实际上您没有那个,并且您有一个数据库连接?哪一个?
要么将所有数据保存在数组列表中,要么将数据保存在数据库中。如果它都在一个数组列表中,那么数据库部分是无关紧要的。如果您没有将所有数据都放在数组列表中,那么您的问题会误导并且不清楚。
如果数据在数据库中,请设置适当的索引并使用 ORDER BY 子句。
推荐阅读
- html - 在引导 div 列中居中 d3 图形的问题
- reactjs - 我可以从进行 API 调用的数据库中获取数据,然后将其传递给进行另一个 API 调用的另一个函数吗
- unit-testing - 如何使用 pytest 对多个数据结构运行相同的测试?
- python - 需要使用 FastAPI 立即发送响应状态代码,同时在后台保持作业同步
- javascript - 不能在 useRouteMatch 中声明 url 和 path 变量
- python - 有没有很好的管理网站登录过程的解决方案?
- json - 将 ansible 变量作为 json 单衬里?
- javascript - 如何使用 JS 在 html 中获取 tagName 的所有父母?
- c - 具有复杂嵌套结构的链接列表不兼容指针错误
- python - 如何在 C++ 中访问 Python 模块?