如果您不创建很多对象,Java 非常快

在本文开始前,先给大家分享几个好用的IDEA激活码

这里提供几个最新的激活码,有需要的朋友可以试试,先到先用:

2022Intellij IDEA最新激活码,IDEA稳定专属激活码(持续更新)

2022Pycharm激活码,Pycharm稳定专属激活码(持续更新)

2022Webstorm激活码,Webstorm稳定专属激活码(持续更新)

2022Phpstorm激活码,Phpstorm稳定专属激活码(持续更新)

2022Goland激活码,Goland稳定专属激活码(持续更新)

 

文着眼于使用Chronicle Wire(开源)中的 net.openhft.chronicle.wire.channel 包以每分钟 40 亿个事件通过 TCP/IP 传递事件的基准测试,以及我们旨在避免对象分配的原因。

关键优化之一是几乎不产生垃圾。分配应该是一个非常便宜的操作,非常短暂的对象的垃圾收集也非常便宜。不分配真的有这样的区别吗?在分摊GC 暂停的吞吐量测试中,每个事件(44 字节)一个小对象对性能有什么影响?

虽然分配尽可能高效,但它无法避免 CPU 的 L1/L2 缓存上的内存压力,并且当许多内核很忙时,它们会争用共享 L3 缓存中的内存。

结果

使用 Ubuntu 22.10 对 Ryzen 5950X 进行基准测试。

如果您不创建很多对象,Java 非常快

* 跨 16 个客户端,双向发送一个事件。平均延迟 = 2 * 16 / 吞吐量
ns:纳秒
M events/s:每秒百万事件

每个事件的一个额外分配增加了 166 ns 左右。这听起来并不多。但是,在这种高度优化的高吞吐量环境中,这会将性能降低 25%。在 Chronicle Wire 中读取事件的默认行为是每次反序列化时都为相同的事件类型重用相同的对象。这提供了一个简单的对象池策略来避免分配。如果这个数据必须被持久化,它必须首先被复制,因为对象被重用以减少对象的创建。

只有 0.3% 的时间在垃圾收集器中

GC 所花费的总时间约为每分钟 170 毫秒或 0.3% 的时间。清理这些非常短暂的对象需要时间的是分配而不是时间。

分配率和平均延迟

仅在多个 CPU 上创建短期 TopOfBook 对象的基准测试会产生类似的结果。这表明即使是少量内核,新对象的分配速率也会很快饱和,从而增加更多线程的平均延迟。这适用于相同的 44 字节小对象。

在带有 Ubuntu 21.10、Java 17.0.4.1 的 Ryzen 5950X 上

如果您不创建很多对象,Java 非常快

基准

如果您不创建很多对象,Java 非常快

在这个基准测试中,16 个客户端连接到一个简单的微服务,该微服务接收每个事件并将其再次发送回来。

来。所有事件都是(反)序列化的具有事件类型的 POJO。这转化为异步 RPC 调用。

爪哇

public class EchoTopOfBookHandler implements TopOfBookHandler {
   private TopOfBookListener topOfBookListener;

   @Override
   public void topOfBook(TopOfBook topOfBook) {
       if (ONE__NEW_OBJECT)
           topOfBook = topOfBook.deepCopy();
       topOfBookListener.topOfBook(topOfBook);
   }

在这种情况下, deepCopy() 创建一个新的 TopOfBook 并设置所有字段。

基准测试可以在两种模式下运行,一种是不分配对象,另一种是分配和初始化任何对象,这使我们能够测量这带来的差异。每个事件都被建模为异步 RPC 调用,以使测试、开发和维护更容易。 

爪哇

public interface TopOfBookListener {
   void topOfBook(TopOfBook topOfBook);
}

低延迟软件可能非常快,但也难以使用,从而减慢开发速度。换句话说,为了创建低延迟软件,开发人员经常采用难以阅读和维护的低级技术。这种开销会减慢您的开发速度。使用 Chronicle Wire,您的数据结构易于阅读和调试,但不会牺牲性能。 

使用在 YAML 中建模的事件,我们可以支持微服务的行为驱动开发

出于测试目的,您的数据可以用简单的 yaml 格式表示,如下所示:

YAML

# This is the in.yaml for the microservice of topOfBook that was described above. 
# first top-of-book
---
topOfBook: {
 sendingTimeNS: 2022-09-05T12:34:56.789012345,
 symbol: EUR/USD,
 ecn: EBS,
 bidPrice: 0.9913,
 askPrice: 0.9917,
 bidQuantity: 1000000,
 askQuantity: 2500000
}
...
# second top-of-book
---
topOfBook: {
 sendingTimeNS: 2022-09-05T12:34:56.789123456,
 symbol: EUR/USD,
 ecn: EBS,
 bidPrice: 0.9914,
 askPrice: 0.9918,
 bidQuantity: 1500000,
 askQuantity: 2000000
}
...

在这里可用。

该库用于编年史服务

结论

Java 可以非常快,但是,避免创建对象是非常值得的。

如果对象的生命周期很短,创建对象的成本可能远高于清理它们的成本。

发布者:admin,转转请注明出处:https://www.ajihuo.com/soft/5024.html

(0)
上一篇 2022年10月17日 下午2:49
下一篇 2022年10月23日 下午3:19

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注