简体   繁体   English

使用静态初始化块来提高性能

[英]using static initialization blocks to improve performance

Given an existing code base being used in production containing a class A that contains a method that populates N fields of another POJO class B using setters and returns the POJO to the caller and given that all instances of class B will be different in regards to only two field ie, N - 2 fields will be the same across all instances of class B, would there be any performance gain if class A has a static reference to class B and initializes the fields of class B that don't change in a static init block? 给定在生产中使用的现有代码库,其中包含一个类A,该类包含使用setter填充另一个POJO类B的N个字段的方法,并将POJO返回给调用者,并且假定B类的所有实例仅在两个字段,即N-2个字段在B类的所有实例中都是相同的,如果A类具有对B类的静态引用并且初始化B类中不会在静态中发生变化的字段,则会有任何性能提升init块? This way, the method in class A that was populating N fields of class B on each call will now have to populate only two fields which are different. 这样,A类中每次调用时填充B类N个字段的方法现在只需要填充两个不同的字段。 This will also eliminate the need to create a new object of type B for each call to the method in class A. What are the implications of this approach in a multi-threaded application? 这也将消除为每次调用A类中的方法创建类型B的新对象的需要。这种方法在多线程应用程序中有什么含义?

Alternately, we can declare all the fields in class B that don't change as static so that the method in class A only sets the fields that change per call. 或者,我们可以声明B类中不会更改为静态的所有字段,以便A类中的方法仅设置每次调用更改的字段。 Either ways, will the performance gain be worth it or this change qualifies as premature optimization? 无论哪种方式,性能增益是否值得,或者这种变化是否属于过早优化?

Example : 示例:

class A { 
     private static B b = new B(); 

     static {
         b.setSystem("MySystem");
         b.setVersion("1.1");
     }

     public B getB(String name) {
         b.setName(name);
         return B;

     }
}

given that all instances of class B will be different in regards to only two field 鉴于B类的所有实例仅在两个领域有所不同

So I understand that you have more than one instance of B 所以我知道你有不止一个B的实例

This will also eliminate the need to create a new object of type B for each call to the method in class A. 这也将消除为每个对A类方法的调用创建类型B的新对象的需要。

But now you only have one instance of B - if A changes those 2 fields, all the places in your code that have a reference to that instance of B will see the change (assuming proper synchronization). 但是现在你只有一个B实例 - 如果A更改了这两个字段,代码中所有引用该B实例的位置都会看到更改(假设正确同步)。

=> It is not clear whether you need one or more instances of B. =>目前尚不清楚是否需要一个或多个B实例。

What are the implications of this approach in a multi-threaded application? 这种方法在多线程应用程序中有什么含义?

If you share the same instance of B accross threads, you need to make sure you use proper synchronization when writing and reading B's properties. 如果您共享B个交叉线程的相同实例,则需要确保在编写和读取B的属性时使用正确的同步。

Alternately, we can declare all the fields in class B that don't change as static 或者,我们可以声明B类中不会更改为静态的所有字段

Do you mean final? 你的意思是最后的?

Either ways, will the performance gain be worth it or this change qualifies as premature optimization? 无论哪种方式,性能增益是否值得,或者这种变化是否属于过早优化?

It think it does qualify indeed. 它认为它确实有资格。 Especially since you don't seem 100% sure yet about what you need. 特别是因为你似乎并不完全确定你需要什么。 So same advice as usual: go the easy and simple way. 和往常一样的建议:简单易行。 IF performance is not good enough, profile and determine what parts of the code need to be improved. 如果性能不够好,请分析并确定需要改进代码的哪些部分。

If you know you are going to be in a multi-threaded environment, you should probably avoid anything static and mutable - that will make your life easier and limit the risk of concurrency bugs. 如果您知道自己将处于多线程环境中,那么您应该避免任何静态和可变的东西 - 这将使您的生活更轻松并限制并发错误的风险。

Ideally, (1) try not to share objects accross threads - if you can't, then (2) try to share immutable objects - if you can't (3) make sure that you use proper synchronization and that you know what you are doing. 理想情况下,(1)尽量不要跨线程共享对象 - 如果你不能,那么(2)尝试共享不可变对象 - 如果你不能(3)确保你使用正确的同步并且你知道你是什么是做。

If you only keep a single instance of class B , which you modify and return from that method as appropriate, then you'll have to expect trouble: a caller cannot rely on the returned object containing the data he requested. 如果你只保留一个B类的实例,你可以根据需要修改并从该方法返回,那么你将不得不遇到麻烦:调用者不能依赖包含他请求的数据的返回对象。 In a single-threaded application, storing that value and accessing it later on will lead to trouble if there was a different call to the method in between. 在单线程应用程序中,如果在两者之间存在对方法的不同调用,则存储该值并稍后访问它将导致麻烦。 In a multi-threaded application, the content might even change without such a call from the current thread, as another thread might call the method and cause the object to change. 在多线程应用程序中,内容甚至可能在没有来自当前线程的调用的情况下发生更改,因为另一个线程可能会调用该方法并导致对象发生更改。 The object might even be in an inconsistent state in between. 对象甚至可能处于不一致状态。

There might be cases where this can be used safely and reasonably, but from the general description you provide I'd advise against it. 在某些情况下,可以安全合理地使用它,但根据您提供的一般说明,我建议不要这样做。 Perhaps a better solution would be factoring out the unchanging part of class B in such a way that B only holds the two changing values and a reference to another object holding the unmodifiable part. 或许更好的解决方案是将B类中不变的部分分解出来,使得B只保存两个变化的值,并且引用另一个保持不可变形部分的对象。 Of course this is only applicable if you control the implementation of B . 当然,这只适用于控制B的实现。

Given a class A containing method that populates N fields of another POJO class B using setters 给定一个包含A类的方法,该方法使用setter填充另一个POJO类B的N个字段

So A has instance of B or List of instances of B? 那么A有B的实例还是B的实例列表?

and returns the POJO to the caller and given that all instances of class B will be different in regards to only two field ie, N - 2 fields will be the same across all instances of class B, 并且将POJO返回给调用者并且假设B类的所有实例仅在两个字段方面是不同的,即N-2个字段在所有B类实例中都是相同的,

Why not to directly initialize N-2 Fields in B itself. 为什么不直接初始化B本身的N-2字段。

would there be any performance gain if class A has a static reference to class B and initializes the fields of class B that don't change in a static init block? 如果类A具有对类B的静态引用并初始化在静态init块中没有更改的类B的字段,那么会有任何性能提升吗? This way, the method in class A that was populating N fields of class B on each call will now have to populate only two fields which are different. 这样,A类中每次调用时填充B类N个字段的方法现在只需要填充两个不同的字段。 This will also eliminate the need to create a new object of type B for each call to the method in class A. What are the implications of this approach in a multi-threaded application? 这也将消除为每次调用A类中的方法创建类型B的新对象的需要。这种方法在多线程应用程序中有什么含义?

If you use Static then B will be part of A class not object of A so B will be common for All A instances do you really want that? 如果你使用Static那么B将是部分A类不是反对A所以B将是通用于所有A实例你真的想要吗?

Alternately, we can declare all the fields in class B that don't change as static so that the method in class A only sets the fields that change per call. 或者,我们可以声明B类中不会更改为静态的所有字段,以便A类中的方法仅设置每次调用更改的字段。 Either ways, will the performance gain be worth it or this change qualifies as premature optimization? 无论哪种方式,性能增益是否值得,或者这种变化是否属于过早优化?

Please provide some code. 请提供一些代码。 In my opinion static blocks should be only used for configuration objects initialization. 在我看来,静态块应该只用于配置对象的初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM