1 Java日志框架性能比較
前面幾章止毕,筆者分別介紹了log4j,logback,log4j2三大日志實現(xiàn)框架劣坊。
接下來比然,就用具體的數(shù)據(jù)比較下,哪個日志框架的性能更好桨嫁!
單線程:外循環(huán)100次,內(nèi)循環(huán)100000次份帐;
多線程:開啟100個線程瞧甩,每個線程執(zhí)行100000次;
1.1 測試代碼:
(1)log4j:
public class log4jDemo {
Logger logger = Logger.getLogger(log4jDemo.class);
@Test
public void testThread() throws InterruptedException {
int THREAD_NUM = 100;
final int LOOP_NUM = 100000;
final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
long start = System.currentTimeMillis();
for(int x= 0;x < THREAD_NUM;x++){
new Thread(new Runnable() {
public void run() {
for (int y = 0; y < LOOP_NUM; y++) {
logger.info("Info Message!");
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();
System.out.println(System.currentTimeMillis() - start);
}
@Test
public void test() throws InterruptedException {
int X_NUM = 100;
int Y_NUM = 100000;
long start = System.currentTimeMillis();
for(int x=0;x < X_NUM;x++) {
for (int y = 0; y < Y_NUM; y++) {
logger.info("Info Message!");
}
}
System.out.print(System.currentTimeMillis() - start);
}
}
(2)logback:
public class logbackDemo {
Logger logger = LoggerFactory.getLogger(logbackDemo.class);
@Test
public void testThread() throws InterruptedException {
int THREAD_NUM = 100;
final int LOOP_NUM = 100000;
final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
long start = System.currentTimeMillis();
for(int x= 0;x < THREAD_NUM;x++){
new Thread(new Runnable() {
public void run() {
for (int y = 0; y < LOOP_NUM; y++) {
logger.info("Info Message!");
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();
System.out.println(System.currentTimeMillis() - start);
}
@Test
public void test() {
int X_NUM = 100;
int Y_NUM = 100000;
long start = System.currentTimeMillis();
for(int x=0;x<X_NUM;x++) {
for (int y = 0; y < Y_NUM; y++) {
logger.info("Info Message!");
}
}
System.out.print(System.currentTimeMillis()-start);
}
}
(3)log4j2:
public class log4j2Demo {
private Logger logger = LogManager.getLogger(log4j2Demo.class);
@Test
public void testThread() throws InterruptedException {
int THREAD_NUM = 100;
final int LOOP_NUM = 100000;
final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
long start = System.currentTimeMillis();
for(int x= 0;x < THREAD_NUM;x++){
new Thread(new Runnable() {
public void run() {
for (int y = 0; y < LOOP_NUM; y++) {
logger.info("Info Message!");
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();
System.out.println(System.currentTimeMillis() - start);
}
@Test
public void test() throws InterruptedException {
int X_NUM = 100;
int Y_NUM = 100000;
long start = System.currentTimeMillis();
for(int x=0;x<X_NUM;x++) {
for (int y = 0; y < Y_NUM; y++) {
logger.info("Info Message!");
}
}
System.out.print(System.currentTimeMillis() - start);
}
}
1.2 配置文件:
(1)log4j:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<!--無緩存弥鹦,立即輸出-->
<appender name="FILE" class="org.apache.log4j.FileAppender">
<param name="File" value="e:/log.out" />
<param name="append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %p %c - %m%n" />
</layout>
</appender>
<!--有緩存肚逸,不立即輸出-->
<appender name="FILE" class="org.apache.log4j.FileAppender">
<param name="File" value="e:/log.out" />
<param name="append" value="true"/>
<param name="immediateFlush" value="false"/>
<param name="bufferedIO" value="true"/>
<param name="bufferSize" value="8192"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %p %c - %m%n" />
</layout>
</appender>
<!--異步appender-->
<appender name="AsyncAppender" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE"/>
</appender>
<root>
<priority value="info" />
<appender-ref ref="FILE" />
<appender-ref ref="AsyncAppender" />
</root>
</log4j:configuration>
(2)logback:
<configuration >
<!--無緩存,立即輸出-->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>e:/log.out</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</pattern>
</encoder>
</appender>
<!--有緩存彬坏,不立即輸出-->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>e:/log.out</file>
<append>true</append>
<immediateFlush>false</immediateFlush>
<bufferSize>8192</bufferSize>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</pattern>
</encoder>
</appender>
<!--異步appender-->
<appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>128</queueSize>
<appender-ref ref ="FILE"/>
</appender>
<root level="info">
<appender-ref ref="ASYNC" />
<appender-ref ref="FILE" />
</root>
</configuration>
(3)log4j2:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
<Appenders>
<!--無緩存朦促,立即輸出-->
<File name="File" fileName="e:/log.out" append="true">
<<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</Pattern>
</PatternLayout>
</File>
<!--有緩存,不立即輸出-->
<File name="File" fileName="e:/log.out" append="true"
immediateFlush="false" bufferedIO="true" bufferSize="8192">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} %p %c - %m%n</Pattern>
</PatternLayout>
</File>
<!--異步appender-->
<Async name="Async">
<AppenderRef ref="File"/>
</Async>
</Appenders>
<Loggers>
<Root level="info" >
<AppenderRef ref="Async"/>
<AppenderRef ref="File"/>
</Root>
<!--異步logger-->
<AsyncRoot level="info" >
<AppenderRef ref="File"/>
</AsyncRoot>
</Loggers>
</Configuration>
1.3 結果比較(毫秒)
筆者從單線程栓始、多線程2種情況下進行的測試务冕!
無論是多線程還是單線程,在啟用緩存的情況下幻赚,系統(tǒng)性能得到了巨大的提升禀忆;
在單線程情況下,相比較來說落恼,啟用異步Appender并沒有對性能有較大的提升箩退!
值得一提的是,在log4j2中佳谦,多線程情況下戴涝,相對于同步logger來說,異步logger并沒有進一步提高系統(tǒng)的性能钻蔑,兩者不相上下啥刻;
但是,對于其他情況而言咪笑,異步logger還是有較大的提升可帽!
-
單線程
(1)單線程,未開啟緩存窗怒,立即刷出 log4j:29772映跟、29959钝满、30911 logback:25423、24552申窘、26006 log4j2:37927弯蚜、38240、40164 (2)單線程剃法,開啟緩存碎捺,不立即刷出 log4j:9858、9677贷洲、9665 logback:5561收厨、5604、5611 log4j2:5782优构、5505诵叁、5499 (3)單線程,異步appender,未開啟緩存钦椭,立即輸出 log4j:29683拧额、29929、29385 logback:33102彪腔、31779侥锦、30516 log4j2:39298、39562德挣、41872 (4)單線程恭垦,異步appender,開啟緩存格嗅,不立即輸出 log4j:10110番挺、10068、10177 logback:8753屯掖、9112玄柏、8922 log4j2:8692、8400懂扼、8252
-
多線程
(1)多線程禁荸,未開啟緩存右蒲,立即刷出 log4j:38541阀湿、37791、38366 logback:35644瑰妄、35463陷嘴、35442 log4j2:38544、38746间坐、38706 (2)多線程灾挨,開啟緩存邑退,不立即刷出 log4j:13296、12938劳澄、12686 logback:6547地技、6294、6576 log4j2:5596秒拔、5423莫矗、5421 (3)多線程,異步appender,未開啟緩存砂缩,立即輸出 log4j:30844作谚、32088、30734 logback:44203庵芭、42191妹懒、43228 log4j2:46804、46034双吆、46232 (4)多線程眨唬,異步appender,開啟緩存好乐,不立即輸出 log4j:10422单绑、10204、10495 logback:40249曹宴、40437搂橙、40173 log4j2:7832、8447笛坦、8660 (5)多線程区转,異步logger,未開啟緩存版扩,立即輸出 log4j2:40555废离、40245、40325 (6)多線程礁芦,異步logger蜻韭,開啟緩存,不立即刷出 log4j2:5319柿扣、5407肖方、5305