用于共享大型不可变对象的工厂/缓存策略

2024-05-19

我的问题很像上一篇文章最佳哈希集初始化 (Scala | Java) https://stackoverflow.com/questions/14714900/optimal-hashset-initialization-scala-java,我想用的地方HashSet为了加速(目前我正在使用Set)但是HashSet没有表现出它的(恒定时间)优势。

对于提到的解决方案:

您可以通过实习来最大限度地降低平等成本。这意味着你 通过工厂方法获取类的新对象,该方法 检查请求的新对象是否已经存在,如果存在, 返回对现有对象的引用。如果你断言每个 这种类型的对象是以这种方式构造的,你知道有 每个不同对象和等于的只有一个实例 相当于对象标识,这是一种廉价的引用比较 (Scala 中的等式)。

但是,我不太确定检查的有效方法是什么

请求的新对象是否已经存在

对于大型对象(例如带有 hashmap 参数的 case 类对象、一些其他对象结构...等)

通过比较每个复杂的字段并不会带来太多的性能优势,不是吗?或者如果是的话还有其他方法吗?

另外,我也很困惑如何制作

等于变成 相当于对象标识,这是一种廉价的引用比较 (Scala 中的等式)。

in code.

我认为,上面提到的意图技术基本上是一种对象缓存。 因此,我参考了帖子中提到的技术Java中小型不可变对象的缓存策略? https://stackoverflow.com/questions/5783839/caching-strategy-for-small-immutable-objects-in-java。但是,我仍然不知道对于大型对象有什么有效的方法。

为了方便起见,我引用了帖子中的缓存技术(Java)///表示我的想法和问题:

private static final int N_POINTS = 10191; 
private static final Point[] POINTS = new Point[N_POINTS];

public static Point of(int x, int y, int z) {
    int h = hash(x,y,z); ///  I can use hash code of each complicated field to construct the value
    int index = (h & 0x7fffffff) % N_POINTS;
    Point p = POINTS[index];
    if (p != null && p.x == x && p.y == y && p.z == z) /// Not working for large objects?
       return p;
    return POINTS[index] = new Point(x,y,z);
} 

总而言之,对大对象实施高效缓存策略的最佳实践是什么,以便我可以利用HashSet在斯卡拉?

Thanks,


实习的目标是使equals要实现的方法使用引用相等 as: this eq that (or this == that在爪哇)。 很明显,该实现将具有最佳的运行时特性 越多传统的 equals比较一些字段集。

仅当存在且仅有一个实例时,此比较才有效 每个“唯一对象”由对象的某些字段集确定。

Intern-ing 仅在以下情况下有效 的前期成本intern手术 可以通过(可能很多)调用的最小化成本来完全抵消equals, 通过驱动HashMap.

正如您所指出的,这intern-ing 可能需要一个潜在昂贵的缓存机制: 有运行时开销(执行检查) 和内存开销(缓存的大小)。

  • 最直接的缓存方法是HashMap,以及传统的equals. hashCode应该偷懒;缓存其结果,因此不需要重新计算。 可能需要考虑线程问题。

  • 实现这种缓存的一种方法是使用trie http://en.wikipedia.org/wiki/Trie,也许在每个节点处用哈希表实现,并且其中每个“级别”对应于对象中的一个字段(第一级别 - 字段 1、第二级别、字段 2 等...),用于“用于的字段集”建立独特性。”

还有其他可行的方法来实现这种缓存。 请原谅我避免进一步讨论此类问题, 请允许我提出一些避免处理该问题的方法。

选项 1:不缓存

Claim: 您可能会获得足够有效的结果 使用快速哈希(并在内部缓存), 的“传统”实现equals, 并从一个开始HashMap or HashSet of 足够的最小尺寸 https://stackoverflow.com/questions/1324064/performance-of-hashmap-with-different-initial-capacity-and-load-factor

理想情况下,哈希表中很少有冲突, 以及拨打电话的次数equals是最小的。

选项 2:将多个字段映射到一个唯一字段String

[此方法假设“唯一定义对象的字段”是不可变的。如果情况并非如此,可以进行适当的调整来补偿。]

构建并缓存private unique: String对应于唯一的对象实例。 例如,对于某些简单对象,以下内容可能是唯一的:

“用于建立唯一性的字段集”的字符串值的串联,以逗号分隔。

了解您的物体/场特征将有助于确定 如何创建这样一个独特的字符串。

有了这样的值,我们就可以避免单独的实习生/缓存机制 并通过实施两者保留大部分好处equals and hashCode就这一点而言unique string:

def equals(thatObj: Any) = thatObj match {
    case that : MyType => unique.equals(that.unique)
    case _             => false
  }

def hashCode() = unique.hashCode

选项 2 的替代方案:

[编辑:Rüdiger Klaehn 提供此链接提供了避免 String.intern() 的令人信服的证据 https://stackoverflow.com/questions/10624232/performance-penalty-of-string-intern]

Use String.intern并调整equals利用它:

private val unique = buildUnique().intern

def equals(thatObj: Any) = thatObj match {
    case that : MyType => unique.eq(that.unique) // In Java: unique == that.unique
    case _             => false
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于共享大型不可变对象的工厂/缓存策略 的相关文章

  • 如何制作行业标准的桌面Java应用程序? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 点击 Java Web 服务:curl 或 URLConnection

    我使用的 Java 服务器在以下 URL 上公开 RESTful API http localhost 8080 my server 文档建议使用curl用于提交简单的PUT请求 文件上传 并强烈建议用户使用与示例中提供的完全相同的参数 所
  • MySQL 和 Hibernate 之间的主键自增由谁负责?

    MySQL CREATE TABLE role id role INT 11 unsigned NOT NULL AUTO INCREMENT PRIMARY KEY id role AUTO INCREMENT 1 休眠 Entity p
  • 将数据传递到表单时的重定向后获取?

    我有几个场景 servlet 需要将数据从数据库检索到的记录传递到 JSP 中的表单 目前 我将此信息存储在请求中 使用 RequestDispatcher 转发到页面 一切都很好 然而 这不符合 PRG 模式 AFAIK 并且当然意味着刷
  • Java 7 中的 Beans Binding 将被什么取代?

    我在某处读到 我忘记了链接 Beans Binding 将不会成为 Java 7 的一部分 有人知道什么会取代它吗 另外 当前版本的 Java 中是否有 Bean 绑定的替代方案 我建议JGoodies 绑定 https binding d
  • 在循环中使用 if 语句? - 加工

    假设我必须在 for 循环中使用 if 语句 并且 for 循环在特定条件下触发 而 if 语句仅在 for 循环达到特定阶段时触发 例如 条件是一个计数器 当发生特定事件 例如球从屏幕上掉下来 时 该计数器会进行计数 每次球穿过屏幕时 都
  • 使用 TLS 证书 JDBC 连接到 Oracle 数据库

    我正在尝试用 Java 编写一个连接类来使用 JDBC 驱动程序连接到 Oracle 数据库 但我想保护用于连接到 Oracle 数据库的参数 例如 jdbcurl 用户名 密码 我必须使用 TLS 证书概念来连接到 Java 中的 Ora
  • 搜索 JTable 时 - 未获得正确的 ID

    所以我尝试在搜索名称后单击表 然后在其他表中编辑它 问题是我没有获得正确的 ID 而只获得第一个 ID JTable https i stack imgur com TnNIq png 搜索行动 https i stack imgur co
  • 此代码签名证书对于签名小程序有效吗?

    我们购买了代码签名证书来签名小程序 但在签名小程序时出现以下错误 C CM WEB INF gt jarsigner keystore code signing keystore C CM SweetApplet jar code sign
  • RecyclerView onItemClickListener 不工作

    我正在研究回收视图并尝试对 recyclerview 的每个项目使用点击侦听器界面 这是我的活动课程 public class LegacyHomeActivity extends ActivityBaseDrawer private Li
  • 在 Graal.js 中使用 java 类

    使用 Graal js 如何将 java 类导入到 JS 脚本中 以下代码适用于 Nashorn JJS 但不适用于 Graal js 因为没有Java type 在graal中 我需要在某个时候调用truffle吗 var ArrayLi
  • Android-如何在指定时间后台下载数据

    我提前很抱歉没有发布任何代码 主要是因为我一生都无法弄清楚我需要如何做我需要做的事情 基本上 在一天中的指定时间间隔 例如下午 5 点 我希望我的应用程序从我的服务器下载一些数据并将其存储在设备上 这是为了减少每次运行应用程序时下载数据对我
  • Preg_match PHP 到 java 的翻译

    我在将 php preg match 转换为 java 时遇到一些问题 我以为我的一切都是正确的 但它似乎不起作用 这是代码 原始PHP Pattern for 44 Character UUID pattern 0 9A F 44 if
  • 多少次函数调用会导致堆栈溢出

    你好 Android Java 开发者 当一个函数调用一个函数并且该函数调用另一个函数等等时 有多少次调用 堆栈长度 会让我陷入堆栈溢出 有一般经验法则吗 我问的原因是因为我现在对于我的 5 人纸牌游戏来说哪个更有效 设计明智 解决方案一
  • 使用 Arrays.copyOf 复制不同类型的数组时出现问题

    我正在尝试创建一个方法 该方法几乎将任何内容作为参数 并返回带有某些分隔符的值的串联字符串表示形式 public static String getConcatenated char delim Object names String st
  • 将文件内容存储到数组中

    我的刽子手程序有问题 我真的认为我需要做的事情超出了我对java的理解 这是我的代码 import java io BufferedReader import java io FileReader import java io FileNo
  • 线程缓存和 Java 内存模型

    我正在尝试了解 Java 内存模型和线程 据我了解 每个线程都有 主 内存的本地副本 因此 如果一个线程尝试更改int变量 例如某个对象的变量 它会缓存int变量 如果它更改它 其他线程可能看不到更改 但是如果线程缓存一些对象而不是 int
  • 使用 Jsoup 选择没有类的 HTML 元素

    考虑一个像这样的 html 文档 div p p p p p class random class name p div 我们怎样才能选择所有p元素 但不包括p元素与random class name class Elements ps b
  • Eclipse IDE - 错误:构建路径指定执行环境 Java SE 1.7

    在 Eclipse 中 我收到一个错误 构建路径指定执行环境Java SE 1 7 工作区中没有安装与此环境严格兼容的 JRE 尝试这个 In Eclipse your project gt properties gt java build
  • 为什么 JDOM 的 getChild() 方法返回 null?

    我正在做一个关于 html 文档操作的项目 我想要现有 html 文档中的正文内容将其修改为新的 html 现在我正在使用 JDOM 我想在我的编码中使用 body 元素 为此 我在编码中使用了 getChild body 但它向我的程序返

随机推荐