The introduction
Two dogs: two fat quick wake up, hurriedly see just alarm email, you last time write save user interface time (” two fat parameters check bumpy road “) greatly rise, hurriedly check the reasons. Two fat: good, see immediately, inner heart drama can be dye-in-the air (in the heart but complain, big midday stir me to get rich dream, just dream of the stock that I buy again rose stop to be awakened). After all, it is my own bug, and I will fix it with tears in my eyes. Two fat to the analysis of this problem or handy, after all, has been a seasoned professional.
Test environment recurring problems
Two fat first through the internal monitoring tools to see whether the network is normal during this period of time, and CPU usage, database time, etc., these indicators seem to be normal, the only slight difference is that this period of traffic rose some, it is certain that the company is spending money on marketing advertising. Then two fat and cat (public comment open source monitoring tool) analysis of several requests, each stage of the time to see down ok. If only the production environment problems could be replicated in the test environment, it would be much easier to solve the problem. Isn’t production flow up a bit? That test environment to pressure test a, two fat decisive download a JMeter (pressure test tool) in the test environment to carry out a crazy pressure test, as expected, and the production of the same problem. If you can reproduce the problem, you’re a big step closer to solving it.
Arthas is faulty
The problem is repeated, and the next step is to figure out where the interface is time-consuming. Generally, we print the time spent in each step by recording logs for places that take a long time to find an interface. This is common practice, but the last time the department technology master “Two Dogs” shared an artifact arthas could output the time on each node on the method path. I have never had a chance to use it for practical operation, but today I can finally practice with it. Installation of what is not introduced, the official website are written in more detail, and the documents are also in Chinese, very easy to use. Let’s use Arthas. The page is successfully started
arthas
trace
org.apache.commons.beanutils.BeanUtils#copyProperties
apache
low
Performance comparison of common attribute assignment operations using the JMH
- use
get
,set
Method replication. cglib
theBeanCopier
.Spring
theBeanUtils
apache
theBeanUtils
MapStruct
Let’s do a performance comparison of the above operations. Write the following test class.
/ * * *@author:
* @Date: 2020/7/11
* @Description: * /
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 5, time = 5)
@Threads(6)
@Fork(1)
@State(value = Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class BeanCopyTest {
@Param(value = {"1"."10"."100"})
private int count;
public UserBO bo;
public BeanCopier copier;
@Setup(Level.Trial) // Initialize the method before all Benchmark runs
public void init(a) {
copier = BeanCopier.create(UserBO.class, UserVO.class, false);
bo = new UserBO();
bo.setUserName("Java financial");
bo.setAge(1);
bo.setIdCard("88888888");
bo.setEmail("Java financial @ qq.com");
}
public static void main(String[] args) throws RunnerException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Options opt = new OptionsBuilder().include(BeanCopyTest.class.getSimpleName()).result("result.json").resultFormat(ResultFormatType.JSON).build();
new Runner(opt).run();
}
/**
* 使用mapStruct来操作
*/
@Benchmark
public void mapStruct(a) {
for (int i = 1; i <= count; i++) { UserVO vo = UserMapping.INSTANCE.converter(bo); }}/** * Manually set and Get */
@Benchmark
public void setAndGet(a) {
for (int i = 1; i <= count; i++) {
UserVO userVO = newUserVO(); userVO.setUserName(bo.getUserName()); userVO.setEmail(bo.getEmail()); userVO.setSex(bo.getSex()); userVO.setIdCard(bo.getIdCard()); userVO.setAge(bo.getAge()); }}/** * Use cglib's copy method */
@Benchmark
public void cglibBeanCopier(a) {
for (int i = 1; i <= count; i++) {
UserVO vo = new UserVO();
copier.copy(bo, vo, null); }}/** * Use the copyProperties method provided by Spring
@Benchmark
public void springBeanUtils(a) {
for (int i = 1; i <= count; i++) {
UserVO vo = newUserVO(); BeanUtils.copyProperties(bo, vo); }}/** * use apache's copyProperties method *@throws InvocationTargetException
* @throws IllegalAccessException
*/
@Benchmark
public void apacheBeanUtils(a) throws InvocationTargetException, IllegalAccessException {
for (int i = 1; i <= count; i++) {
UserVO vo = newUserVO(); org.apache.commons.beanutils.BeanUtils.copyProperties(vo, bo); }}Copy the code
The final test results are as follows:
Benchmark (count) Mode Cnt Score Error Units
BeanCopyTest.apacheBeanUtils 1 avgt 5 2462103.419 ± 2292830.495 ns/op
BeanCopyTest.apacheBeanUtils 10 avgt 5 21025926.689 ± 11254755.603 ns/op
BeanCopyTest.apacheBeanUtils 100 avgt 5 193235312.113 ± 37929707.246 ns/op
BeanCopyTest.cglibBeanCopier 1 avgt 5 4.936 ± 1.187 ns/op
BeanCopyTest.cglibBeanCopier 10 avgt 5 4.820 ± 1.963 ns/op
BeanCopyTest.cglibBeanCopier 100 avgt 5 4.269 ± 0.890 ns/op
BeanCopyTest.mapStruct 1 avgt 5 4.809 ± 1.720 ns/op
BeanCopyTest.mapStruct 10 avgt 5 4.947 ± 1.320 ns/op
BeanCopyTest.mapStruct 100 avgt 5 4.440 ± 1.191 ns/op
BeanCopyTest.setAndGet 1 avgt 5 3.780 ± 1.785 ns/op
BeanCopyTest.setAndGet 10 avgt 5 3.930 ± 1.788 ns/op
BeanCopyTest.setAndGet 100 avgt 5 4.069 ± 2.181 ns/op
BeanCopyTest.springBeanUtils 1 avgt 5 1190.563 ± 165.574 ns/op
BeanCopyTest.springBeanUtils 10 avgt 5 10887.244 ± 1228.026 ns/op
BeanCopyTest.springBeanUtils 100 avgt 5 109686.562 ± 7485.261 ns/op
Copy the code
- From the above conclusion we can find that the best performance is ranking
get
,set
Method replication, followed bymapStruct
andThe additional BeanCopier
, and thenSpring's beanUtils
And finallyThe apache BeanUtils
. - If you are interested in the above test performance, the code has been uploaded
github
You can download and run the results.The code address - about
JMH
The use of is not introduced, interested in Google. But if you want to do a performance comparison, which is really recommended, you can export the resultsjson
The file then generates the chart.
Why does apacheBeanUtils have the worst performance
Both apacheBeanUtils and Spring’s beanUtils are assigned using reflection, so why is apacheBeanUtils performing worse? There are no secrets under the source code, so let’s take a look at the source code for this method.
Apache BeanUtils
-
Spring’s beanUtil directly uses reflection province, clean, the core code is shown in the following figure.
-
In fact, in ** “Alibaba Development Manual” ** (can be obtained in the public number [Java Finance] reply “Taishan”) there is also a description of the attribute of copy to avoid using apcheBeanUtils
-
If you want to replace Spring BeanUtils with Apache BeanUtils in your production environment, you need to be careful that both of these methods are copyProperties but their arguments are reversed, so don’t just change the package name that you introduced.
conclusion
- Words in actual use are generally not used
get
andset
Method copying, easy to miss properties and also a physical task. It is recommended to usemapStruct
, during compilation,MapStruct
An implementation of this interface is generated, and it can also implement mappings of different names, such as thename
Map tousername
, the flexibility is high. - Two fat feeling today harvest full ah, a learned
jmeter
,arthas
,JMH
The use of three software.
The end of the
- Due to their lack of knowledge, it is hard to avoid mistakes, if you find the wrong place, also hope to leave a message to me to point out, I will correct it.
- If you think the article is good, your retweet, share, praise, like, comment is the biggest encouragement to me.
- Thank you for reading. I very much welcome and thank you for your attention.