ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/test/org/apache/catalina/valves/Benchmarks.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/test/org/apache/catalina/valves/Benchmarks.java
Status
scanned
Type
file
Name
Benchmarks.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
18277 (17.8 KB)
MD5
52ca526bf8a293ee6e13a421fcdda810
SHA1
6565947518551a95a8a569fdb819e1e9e255c258
SHA256
5092d7b5548d5d165ee2685c5cdf39e6eee62d8fbe05208294f2301a6e092bf0
SHA512

      
    
SHA1_git
a83a350bd23f28b2bcb173e8d5c42e93d5c9699c
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
Benchmarks.java | 17.8 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.valves; import java.text.SimpleDateFormat; import java.util.Date; import org.junit.Test; /** * Some simple micro-benchmarks to help determine best approach for thread safety in valves, particularly the * {@link AccessLogValve}. Implemented as JUnit tests to make the simple to execute but does not used Test* as the class * name to avoid being included in the automated unit tests. */ public class Benchmarks { @Test public void testAccessLogGetDate() throws Exception { // Is it better to use a sync or a thread local here? BenchmarkTest benchmark = new BenchmarkTest(); Runnable[] tests = new Runnable[] { new GetDateBenchmarkTest_Sync(), new GetDateBenchmarkTest_Local(), new GetDateBenchmarkTest_LocalMutableLong(), new GetDateBenchmarkTest_LocalStruct() }; benchmark.doTest(5, tests); } private static class GetDateBenchmarkTest_Sync implements Runnable { @Override public String toString() { return "Syncs"; } private volatile long currentMillis = 0; private volatile Date currentDate = null; @Override public void run() { getCurrentDate(); } public Date getCurrentDate() { long systime = System.currentTimeMillis(); if ((systime - currentMillis) > 1000) { synchronized (this) { if ((systime - currentMillis) > 1000) { currentDate = new Date(systime); currentMillis = systime; } } } return currentDate; } } private static class GetDateBenchmarkTest_Local implements Runnable { @Override public String toString() { return "ThreadLocals"; } private ThreadLocal<Long> currentMillisLocal = new ThreadLocal<>() { @Override protected Long initialValue() { return Long.valueOf(0); } }; private ThreadLocal<Date> currentDateLocal = new ThreadLocal<>(); @Override public void run() { getCurrentDate(); } public Date getCurrentDate() { long systime = System.currentTimeMillis(); if ((systime - currentMillisLocal.get().longValue()) > 1000) { currentDateLocal.set(new Date(systime)); currentMillisLocal.set(Long.valueOf(systime)); } return currentDateLocal.get(); } } private static class GetDateBenchmarkTest_LocalMutableLong implements Runnable { @Override public String toString() { return "ThreadLocals with a mutable Long"; } private static class MutableLong { long value = 0; } private ThreadLocal<MutableLong> currentMillisLocal = new ThreadLocal<>() { @Override protected MutableLong initialValue() { return new MutableLong(); } }; private ThreadLocal<Date> currentDateLocal = new ThreadLocal<>(); @Override public void run() { getCurrentDate(); } public Date getCurrentDate() { long systime = System.currentTimeMillis(); if ((systime - currentMillisLocal.get().value) > 1000) { currentDateLocal.set(new Date(systime)); currentMillisLocal.get().value = systime; } return currentDateLocal.get(); } } private static class GetDateBenchmarkTest_LocalStruct implements Runnable { @Override public String toString() { return "single ThreadLocal"; } // note, that we can avoid (long -> Long) conversion private static class Struct { public long currentMillis = 0; public Date currentDate; } private ThreadLocal<Struct> currentStruct = new ThreadLocal<>() { @Override protected Struct initialValue() { return new Struct(); } }; @Override public void run() { getCurrentDate(); } public Date getCurrentDate() { Struct struct = currentStruct.get(); long systime = System.currentTimeMillis(); if ((systime - struct.currentMillis) > 1000) { struct.currentDate = new Date(systime); struct.currentMillis = systime; } return struct.currentDate; } } @Test public void testAccessLogTimeDateElement() throws Exception { // Is it better to use a sync or a thread local here? BenchmarkTest benchmark = new BenchmarkTest(); Runnable[] tests = new Runnable[] { new TimeDateElementBenchmarkTest_Sync(), new TimeDateElementBenchmarkTest_Local(), new TimeDateElementBenchmarkTest_LocalStruct(), new TimeDateElementBenchmarkTest_LocalStruct_SBuilder() }; benchmark.doTest(5, tests); } private abstract static class TimeDateElementBenchmarkTestBase { protected static final String months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; protected String lookup(String month) { int index; try { index = Integer.parseInt(month) - 1; } catch (Throwable t) { index = 0; // cannot happen, in theory } return months[index]; } } private static class TimeDateElementBenchmarkTest_Sync extends TimeDateElementBenchmarkTestBase implements Runnable { @Override public String toString() { return "Syncs"; } private volatile Date currentDate = new Date(); private volatile String currentDateString = null; private SimpleDateFormat dayFormatter = new SimpleDateFormat("dd"); private SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); private SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); private SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss"); @Override public void run() { printDate(); } public String printDate() { StringBuilder buf = new StringBuilder(); Date date = getDateSync(); if (currentDate != date) { synchronized (this) { if (currentDate != date) { StringBuilder current = new StringBuilder(32); current.append('['); current.append(dayFormatter.format(date)); // Day current.append('/'); current.append(lookup(monthFormatter.format(date))); // Month current.append('/'); current.append(yearFormatter.format(date)); // Year current.append(':'); current.append(timeFormatter.format(date)); // Time current.append(']'); currentDateString = current.toString(); currentDate = date; } } } buf.append(currentDateString); return buf.toString(); } private Date getDateSync() { long systime = System.currentTimeMillis(); if ((systime - currentDate.getTime()) > 1000) { synchronized (this) { if ((systime - currentDate.getTime()) > 1000) { currentDate.setTime(systime); } } } return currentDate; } } private static class TimeDateElementBenchmarkTest_Local extends TimeDateElementBenchmarkTestBase implements Runnable { @Override public String toString() { return "ThreadLocals"; } private ThreadLocal<String> currentDateStringLocal = new ThreadLocal<>(); private ThreadLocal<Date> currentDateLocal = new ThreadLocal<>() { @Override protected Date initialValue() { return new Date(); } }; private ThreadLocal<SimpleDateFormat> dayFormatterLocal = new ThreadLocal<>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("dd"); } }; private ThreadLocal<SimpleDateFormat> monthFormatterLocal = new ThreadLocal<>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("MM"); } }; private ThreadLocal<SimpleDateFormat> yearFormatterLocal = new ThreadLocal<>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy"); } }; private ThreadLocal<SimpleDateFormat> timeFormatterLocal = new ThreadLocal<>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("hh:mm:ss"); } }; @Override public void run() { printDate(); } public String printDate() { getDateLocal(); if (currentDateStringLocal.get() == null) { StringBuilder current = new StringBuilder(32); current.append('['); current.append(dayFormatterLocal.get().format(currentDateLocal.get())); // Day current.append('/'); current.append(lookup(monthFormatterLocal.get().format(currentDateLocal.get()))); // Month current.append('/'); current.append(yearFormatterLocal.get().format(currentDateLocal.get())); // Year current.append(':'); current.append(timeFormatterLocal.get().format(currentDateLocal.get())); // Time current.append(']'); currentDateStringLocal.set(current.toString()); } return currentDateStringLocal.get(); } private Date getDateLocal() { long systime = System.currentTimeMillis(); if ((systime - currentDateLocal.get().getTime()) > 1000) { currentDateLocal.get().setTime(systime); currentDateStringLocal.set(null); } return currentDateLocal.get(); } } private static class TimeDateElementBenchmarkTest_LocalStruct extends TimeDateElementBenchmarkTestBase implements Runnable { @Override public String toString() { return "single ThreadLocal"; } private static class Struct { public String currentDateString; public Date currentDate = new Date(); public SimpleDateFormat dayFormatter = new SimpleDateFormat("dd"); public SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); public SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); public SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss"); } private ThreadLocal<Struct> structLocal = new ThreadLocal<>() { @Override protected Struct initialValue() { return new Struct(); } }; @Override public void run() { printDate(); } public String printDate() { getDateLocal(); Struct struct = structLocal.get(); if (struct.currentDateString == null) { StringBuilder current = new StringBuilder(32); current.append('['); current.append(struct.dayFormatter.format(struct.currentDate)); // Day current.append('/'); current.append(lookup(struct.monthFormatter.format(struct.currentDate))); // Month current.append('/'); current.append(struct.yearFormatter.format(struct.currentDate)); // Year current.append(':'); current.append(struct.timeFormatter.format(struct.currentDate)); // Time current.append(']'); struct.currentDateString = current.toString(); } return struct.currentDateString; } private Date getDateLocal() { Struct struct = structLocal.get(); long systime = System.currentTimeMillis(); if ((systime - struct.currentDate.getTime()) > 1000) { struct.currentDate.setTime(systime); struct.currentDateString = null; } return struct.currentDate; } } private static class TimeDateElementBenchmarkTest_LocalStruct_SBuilder extends TimeDateElementBenchmarkTestBase implements Runnable { @Override public String toString() { return "single ThreadLocal, with StringBuilder"; } private static class Struct { public String currentDateString; public Date currentDate = new Date(); public SimpleDateFormat dayFormatter = new SimpleDateFormat("dd"); public SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); public SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); public SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss"); } private ThreadLocal<Struct> structLocal = new ThreadLocal<>() { @Override protected Struct initialValue() { return new Struct(); } }; @Override public void run() { printDate(); } public String printDate() { getDateLocal(); Struct struct = structLocal.get(); if (struct.currentDateString == null) { StringBuilder current = new StringBuilder(32); current.append('['); current.append(struct.dayFormatter.format(struct.currentDate)); // Day current.append('/'); current.append(lookup(struct.monthFormatter.format(struct.currentDate))); // Month current.append('/'); current.append(struct.yearFormatter.format(struct.currentDate)); // Year current.append(':'); current.append(struct.timeFormatter.format(struct.currentDate)); // Time current.append(']'); struct.currentDateString = current.toString(); } return struct.currentDateString; } private Date getDateLocal() { Struct struct = structLocal.get(); long systime = System.currentTimeMillis(); if ((systime - struct.currentDate.getTime()) > 1000) { struct.currentDate.setTime(systime); struct.currentDateString = null; } return struct.currentDate; } } private static class BenchmarkTest { public void doTest(int threadCount, Runnable[] tests) throws Exception { for (int iterations = 1000000; iterations < 10000001; iterations += 1000000) { for (Runnable test : tests) { doTestInternal(threadCount, iterations, test); } } } private void doTestInternal(int threadCount, int iterations, Runnable test) throws Exception { long start = System.currentTimeMillis(); Thread[] threads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { threads[i] = new Thread(new TestThread(iterations, test)); } for (int i = 0; i < threadCount; i++) { threads[i].start(); } for (int i = 0; i < threadCount; i++) { threads[i].join(); } long end = System.currentTimeMillis(); System.out.println(test.getClass().getSimpleName() + ": " + threadCount + " threads and " + iterations + " iterations using " + test + " took " + (end - start) + "ms"); } } private static class TestThread implements Runnable { private int count; private Runnable test; TestThread(int count, Runnable test) { this.count = count; this.test = test; } @Override public void run() { for (int i = 0; i < count; i++) { test.run(); } } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
8.67
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9