Permalink
Browse files

Initial, all benchmarks implemented

  • Loading branch information...
0 parents commit 1add1fdfa06707b9341ba65ed5d22a4e1fab930a @nurkiewicz committed Jan 12, 2013
@@ -0,0 +1,3 @@
+target
+*.iml
+.idea
184 pom.xml
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.blogspot.nurkiewicz</groupId>
+ <artifactId>cacheable-benchmark</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <org.springframework.version>3.2.0.RELEASE</org.springframework.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.scala-lang</groupId>
+ <artifactId>scala-library</artifactId>
+ <version>2.9.1</version>
+ </dependency>
+
+ <!-- Utilities -->
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easytesting</groupId>
+ <artifactId>fest-assert</artifactId>
+ <version>1.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.scalatest</groupId>
+ <artifactId>scalatest_2.9.1</artifactId>
+ <version>1.6.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>13.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.caliper</groupId>
+ <artifactId>caliper</artifactId>
+ <version>0.5-rc1</version>
+ </dependency>
+
+ <!-- Spring framework -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${org.springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <version>${org.springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ <version>${org.springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate.javax.persistence</groupId>
+ <artifactId>hibernate-jpa-2.0-api</artifactId>
+ <version>1.0.1.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ <version>${org.springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>2.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>1.6.11</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.scala-tools</groupId>
+ <artifactId>maven-scala-plugin</artifactId>
+ <version>2.15.1</version>
+ <executions>
+ <execution>
+ <id>compile</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <phase>compile</phase>
+ </execution>
+ <execution>
+ <id>test-compile</id>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <phase>test-compile</phase>
+ </execution>
+ <execution>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.0</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.9</version>
+ <configuration>
+ <argLine>-XX:MaxPermSize=200m</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <version>1.4</version>
+ <configuration>
+ <sources>
+ <source>
+ <basedir>src/main/java</basedir>
+ <excludes>
+ <exclude>**/PlainCalculator.java</exclude>
+ </excludes>
+ </source>
+ </sources>
+ <complianceLevel>1.6</complianceLevel>
+ <aspectLibraries>
+ <aspectLibrary>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ </aspectLibrary>
+ </aspectLibraries>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
@@ -0,0 +1,26 @@
+package com.blogspot.nurkiewicz.cacheable;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 1/12/13, 1:33 PM
+ */
+public aspect ManualCachingAspect {
+
+ private final Map<Integer, Integer> cache = new ConcurrentHashMap<Integer, Integer>();
+
+ pointcut cacheMethodExecution(int x): execution(int com.blogspot.nurkiewicz.cacheable.calculator.ManuallyInstrumentedCalculator.identity(int)) && args(x);
+
+ Object around(int x): cacheMethodExecution(x) {
+ final Integer existing = cache.get(x);
+ if (existing != null) {
+ return existing;
+ }
+ final Object newValue = proceed(x);
+ cache.put(x, (Integer)newValue);
+ return newValue;
+ }
+
+}
@@ -0,0 +1,11 @@
+package com.blogspot.nurkiewicz.cacheable.calculator;
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 1/12/13, 1:42 PM
+ */
+public interface Calculator {
+
+ int identity(int x);
+
+}
@@ -0,0 +1,14 @@
+package com.blogspot.nurkiewicz.cacheable.calculator;
+
+import com.blogspot.nurkiewicz.cacheable.calculator.Calculator;
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 1/12/13, 1:45 PM
+ */
+public class ManuallyInstrumentedCalculator implements Calculator {
+ @Override
+ public int identity(int x) {
+ return x;
+ }
+}
@@ -0,0 +1,13 @@
+package com.blogspot.nurkiewicz.cacheable.calculator;
+
+import org.springframework.cache.annotation.Cacheable;
+
+public class PlainCalculator implements Calculator {
+
+ @Cacheable("identity")
+ @Override
+ public int identity(int x) {
+ return x;
+ }
+
+}
@@ -0,0 +1,17 @@
+package com.blogspot.nurkiewicz.cacheable.calculator;
+
+import org.springframework.cache.annotation.Cacheable;
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 1/12/13, 12:36 PM
+ */
+public class SpringInstrumentedCalculator implements Calculator {
+
+ @Override
+ @Cacheable("identity")
+ public int identity(int x) {
+ return x;
+ }
+
+}
@@ -0,0 +1,41 @@
+package com.blogspot.nurkiewicz.cacheable
+
+import calculator.Calculator
+import com.google.caliper.SimpleBenchmark
+import org.springframework.context.annotation.AnnotationConfigApplicationContext
+
+/**
+ * @author Tomasz Nurkiewicz
+ * @since 1/12/13, 12:07 AM
+ */
+class CacheableBenchmark extends SimpleBenchmark {
+
+ val noCaching: Calculator = fromSpringContext(classOf[NoCachingConfig])
+ val manualCaching: Calculator = fromSpringContext(classOf[ManualCachingConfig])
+ val cacheableCglib: Calculator = fromSpringContext(classOf[CacheableCglibConfig])
+ val cacheableJdkProxy: Calculator = fromSpringContext(classOf[CacheableJdkProxyConfig])
+ val cacheableAspectJ: Calculator = fromSpringContext(classOf[CacheableAspectJWeaving])
+ val aspectJCustom: Calculator = fromSpringContext(classOf[AspectJCustomAspect])
+
+ println("=" * 80)
+
+ def fromSpringContext[T <: BaseConfig](config: Class[T]) =
+ new AnnotationConfigApplicationContext(config).getBean(classOf[Calculator])
+
+ def benchmarkWith(calculator: Calculator, reps: Int) = {
+ var i = reps
+ var accum = 0L
+ while(i > 0) {
+ accum += calculator.identity(i % 10)
+ i -= 1
+ }
+ accum
+ }
+
+ def timeNoCaching(reps: Int) = benchmarkWith(noCaching, reps)
+ def timeManualCaching(reps: Int) = benchmarkWith(manualCaching, reps)
+ def timeCacheableWithCglib(reps: Int) = benchmarkWith(cacheableCglib, reps)
+ def timeCacheableWithJdkProxy(reps: Int) = benchmarkWith(cacheableJdkProxy, reps)
+ def timeCacheableWithAspectJWeaving(reps: Int) = benchmarkWith(cacheableAspectJ, reps)
+ def timeAspectJCustom(reps: Int) = benchmarkWith(aspectJCustom, reps)
+}
@@ -0,0 +1,20 @@
+package com.blogspot.nurkiewicz.cacheable
+
+import calculator.Calculator
+import org.springframework.cache.annotation.Cacheable
+import org.springframework.stereotype.Service
+import org.springframework.beans.factory.annotation.Configurable
+import collection.JavaConversions._
+
+
+class CachingCalculatorDecorator(target: Calculator) extends Calculator {
+ private val cache = new java.util.concurrent.ConcurrentHashMap[java.lang.Integer, java.lang.Integer]
+
+ override def identity(x: Int) = cache.get(x) match {
+ case null =>
+ val v = target.identity(x)
+ cache.put(x, v)
+ v
+ case v => v
+ }
+}
@@ -0,0 +1,59 @@
+package com.blogspot.nurkiewicz.cacheable
+
+import calculator.{ManuallyInstrumentedCalculator, SpringInstrumentedCalculator, Calculator, PlainCalculator}
+import org.springframework.context.annotation.{Primary, AdviceMode, Bean, Configuration}
+import org.springframework.cache.annotation.EnableCaching
+import org.springframework.cache.CacheManager
+import org.springframework.cache.concurrent.ConcurrentMapCacheManager
+import org.springframework.cache.support.NoOpCacheManager
+
+abstract class BaseConfig {
+
+ @Bean
+ def calculator(): Calculator = new PlainCalculator()
+
+}
+
+@Configuration
+class NoCachingConfig extends BaseConfig
+
+@Configuration
+class ManualCachingConfig extends BaseConfig {
+ @Bean
+ override def calculator() = new CachingCalculatorDecorator(super.calculator())
+
+}
+
+@Configuration
+abstract class CacheManagerConfig extends BaseConfig {
+
+ @Bean
+ def cacheManager(): CacheManager = new ConcurrentMapCacheManager()
+
+}
+
+@Configuration
+@EnableCaching(proxyTargetClass = true)
+class CacheableCglibConfig extends CacheManagerConfig
+
+@Configuration
+@EnableCaching(proxyTargetClass = false)
+class CacheableJdkProxyConfig extends CacheManagerConfig
+
+@Configuration
+@EnableCaching(mode = AdviceMode.ASPECTJ)
+class CacheableAspectJWeaving extends CacheManagerConfig {
+
+ @Bean
+ override def calculator() = new SpringInstrumentedCalculator
+
+}
+
+@Configuration
+@EnableCaching(mode = AdviceMode.ASPECTJ)
+class AspectJCustomAspect extends CacheManagerConfig {
+
+ @Bean
+ override def calculator() = new ManuallyInstrumentedCalculator
+
+}
Oops, something went wrong.

0 comments on commit 1add1fd

Please sign in to comment.