Writing High-Performance Application

The Problem
Some features/functions are time consuming or time sensitive, we want to make it as fast as possible.
The following are some tips that I learned form my experience and past mistakes.

Does performance really matter?
Whether the function is time consuming or time sensitive?
If so, do take time to measure performance and optimize it. 

Know the function
What it does? What expensive (db/remote)APIs/Services it calls? How many times it calls?
Can we cache results?

Measure the performance
Use Guava StopWatch to measure time consuming functions and analyze where it spends most of the time. 
Use AspectJ to log slow calls.

Test with real data
If the function handles a lot of data, then test it with a lot of data.

Test with real data can also uncover other issues/bugs in the code.
It would be good if we can get backup of production data to do test; if not, use JMeter, postman runner, newman or write test code to inject data.

Postman already generates code(use OK Http or unirest in java) for request, just introduce some randomness, use threadpool and run it x times.

Change/Optimize only one thing each step, then compare the performance

Use Cache aggressively
For example, to cache query from solr or db, we can split query to non-user related and cache the results, and do user related post filtering in the code.

Parallelization - Avoid Putting things in Series
Use Spring ThreadPoolTaskExecutor
-- Thread creation is expensive, don't create a new thread each time, instead use thread pool.
-- Use common shared thread pool, instead create a new thread pool and kill it after all tasks are done.

ThreadPool Configuration
Know what tasks the pool runs, are they CPU bound or I/O bound?Use different settings for different cases.
Understand how Java ThreadPool works
-- Rules of a ThreadPoolExecutor pool size

  1. If the number of threads is less than the corePoolSize, create a new Thread to run a new task.
  2. If the number of threads is equal (or greater than) the corePoolSize, put the task into the queue.
  3. If the queue is full, and the number of threads is less than the maxPoolSize, create a new thread to run tasks in.
  4. If the queue is full, and the number of threads is greater than or equal to maxPoolSize, reject the task.
new threads are only created when the queue fills up, so if you’re using an unbounded queue then the number of threads will not exceed corePoolSize.

Sample Code
@Configuration
public class TaskExecutorConfig implements AsyncConfigurer {
  @Bean @Override
  public Executor getAsyncExecutor() {
      final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

      final int cpus = Runtime.getRuntime().availableProcessors();
      final int corePoolSize = cpus * defaultScaleFactor;
      executor.setCorePoolSize(corePoolSize);
      final int maxPoolSize = cpus * maxScaleFactor;
      executor.setMaxPoolSize(maxPoolSize);
      executor.setQueueCapacity(queueCapacity);
      executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

      executor.setThreadNamePrefix(ASYNC_EXECUTOR_PREFIX);
      executor.initialize();
      return executor;
  }
}

Use CompletableFuture/RX-Java

Use Hystrix to defend failures from third-party services and Fail Fast

Use profile tools(VisualVM)
-- Monitor memory usage and profile cpu
-- Use the method name filter to only show method we care.
This can give us a high level of the code, what methods it calls and how many times etc.
Post a Comment

Labels

Java (159) Lucene-Solr (110) Interview (61) All (58) J2SE (53) Algorithm (45) Soft Skills (36) Eclipse (34) Code Example (31) Linux (24) JavaScript (23) Spring (22) Windows (22) Web Development (20) Nutch2 (18) Tools (18) Bugs (17) Debug (15) Defects (14) Text Mining (14) J2EE (13) Network (13) PowerShell (11) Troubleshooting (11) Chrome (9) Design (9) How to (9) Learning code (9) Performance (9) UIMA (9) html (9) Http Client (8) Maven (8) Problem Solving (8) Security (8) bat (8) blogger (8) Big Data (7) Continuous Integration (7) Google (7) Guava (7) JSON (7) ANT (6) Coding Skills (6) Database (6) Scala (6) Shell (6) css (6) Algorithm Series (5) Cache (5) Dynamic Languages (5) IDE (5) Lesson Learned (5) Programmer Skills (5) Tips (5) adsense (5) xml (5) AIX (4) Code Quality (4) GAE (4) Git (4) Good Programming Practices (4) Jackson (4) Memory Usage (4) Miscs (4) OpenNLP (4) Project Managment (4) Spark (4) System Design (4) Testing (4) ads (4) regular-expression (4) Android (3) Apache Spark (3) Become a Better You (3) Concurrency (3) Eclipse RCP (3) English (3) Happy Hacking (3) IBM (3) J2SE Knowledge Series (3) JAX-RS (3) Jetty (3) Restful Web Service (3) Script (3) regex (3) seo (3) .Net (2) Android Studio (2) Apache (2) Apache Procrun (2) Architecture (2) Batch (2) Bit Operation (2) Build (2) Building Scalable Web Sites (2) C# (2) C/C++ (2) CSV (2) Career (2) Cassandra (2) Distributed (2) Fiddler (2) Firefox (2) Google Drive (2) Gson (2) How to Interview (2) Html Parser (2) Http (2) Image Tools (2) JQuery (2) Jersey (2) LDAP (2) Life (2) Logging (2) Python (2) Software Issues (2) Storage (2) Text Search (2) xml parser (2) AOP (1) Application Design (1) AspectJ (1) Chrome DevTools (1) Cloud (1) Codility (1) Data Mining (1) Data Structure (1) ExceptionUtils (1) Exif (1) Feature Request (1) FindBugs (1) Greasemonkey (1) HTML5 (1) Httpd (1) I18N (1) IBM Java Thread Dump Analyzer (1) JDK Source Code (1) JDK8 (1) JMX (1) Lazy Developer (1) Mac (1) Machine Learning (1) Mobile (1) My Plan for 2010 (1) Netbeans (1) Notes (1) Operating System (1) Perl (1) Problems (1) Product Architecture (1) Programming Life (1) Quality (1) Redhat (1) Redis (1) Review (1) RxJava (1) Solutions logs (1) Team Management (1) Thread Dump Analyzer (1) Visualization (1) boilerpipe (1) htm (1) ongoing (1) procrun (1) rss (1)

Popular Posts