# Richard Startin's Blog

Published articles for Richard Startin's Blog.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## How Async-Profiler's crash handler works

DevFeed: [How Async-Profiler's crash handler works](<https://devfeed.tech/articles/how-async-profiler-s-crash-handler-works-25637.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/async-profiler-crash-handler>)

Author: Richard Startin's Blog

Published: 2023-11-12T00:00:00Z

Content type: article

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [async](<https://devfeed.tech/topics/async.md>), [c/c++](<https://devfeed.tech/topics/c-c-plus-plus.md>), [Linux](<https://devfeed.tech/topics/linux.md>), [Java](<https://devfeed.tech/topics/java.md>), [JIT](<https://devfeed.tech/topics/jit.md>), [Programming](<https://devfeed.tech/topics/programming.md>)

Tags: [async](<https://devfeed.tech/tags/async.md>), [c](<https://devfeed.tech/tags/c.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [crash](<https://devfeed.tech/tags/crash.md>), [handler](<https://devfeed.tech/tags/handler.md>), [jit](<https://devfeed.tech/tags/jit.md>), [kernel](<https://devfeed.tech/tags/kernel.md>), [linux](<https://devfeed.tech/tags/linux.md>), [memory-safety](<https://devfeed.tech/tags/memory-safety.md>), [profiling](<https://devfeed.tech/tags/profiling.md>), [programming](<https://devfeed.tech/tags/programming.md>), [programming-language](<https://devfeed.tech/tags/programming-language.md>), [run](<https://devfeed.tech/tags/run.md>), [safety](<https://devfeed.tech/tags/safety.md>), [signal](<https://devfeed.tech/tags/signal.md>)

### AI overview

This article explains how async-profiler uses Linux signals and signal handlers to inspect thread state and safely dereference arbitrary pointers without crashing the JVM. It introduces signal-based sampling and frame-pointer unwinding, including the role of JIT-compiled code.

### Source excerpt

Raw pointers in C/C++ open up entire classes of error that are practically unimaginable in higher level languages. So why does anybody use them at all? Unfortunately, it's impossible to write a profiler without getting close to some of the sharp edges of unsafe memory. The async-profiler code base contains a lot of low level tricks, and it's worth studying how some of them work.

## Understanding Request Latency with Profiling

DevFeed: [Understanding Request Latency with Profiling](<https://devfeed.tech/articles/understanding-request-latency-with-profiling-25645.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/wallclock-profiler>)

Author: Richard Startin's Blog

Published: 2023-09-05T00:00:00Z

Content type: article

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Latency](<https://devfeed.tech/topics/latency.md>), [Java](<https://devfeed.tech/topics/java.md>), [datadog](<https://devfeed.tech/topics/datadog.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [analysis](<https://devfeed.tech/tags/analysis.md>), [applications](<https://devfeed.tech/tags/applications.md>), [backend](<https://devfeed.tech/tags/backend.md>), [blog](<https://devfeed.tech/tags/blog.md>), [code](<https://devfeed.tech/tags/code.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [datadog](<https://devfeed.tech/tags/datadog.md>), [java](<https://devfeed.tech/tags/java.md>), [latency](<https://devfeed.tech/tags/latency.md>), [profiling](<https://devfeed.tech/tags/profiling.md>), [request](<https://devfeed.tech/tags/request.md>), [root-cause-analysis](<https://devfeed.tech/tags/root-cause-analysis.md>)

### AI overview

This article explains how Datadog's Java wallclock profiler can help investigate high request latency when time spent off CPU, rather than CPU time, is the likely cause. It discusses using profiling to support root-cause analysis without changing or even seeing the application code.

### Source excerpt

It can be hard to figure out why response times are high in Java applications. In my experience, people either apply a process of elimination to a set of recent commits, or might sometimes use profiles of the system to explain changes in metrics. Making guesses about recent commits can be frustrating for a number of reasons, but mostly because even if you pinpoint the causal change, you still might not know why it was a bad change and are left in limbo. In theory, using a profiler makes root cause analysis a part of the triage process, so adopting continuous profiling should make this whole process easier, but using profilers can be frustrating because you're using the wrong type of profile for analysis. Lots of profiling data focuses on CPU time, but the cause of your latency problem may be related to time spent off CPU instead. This post is about Datadog's Java wallclock profiler, which I worked on last year, and explores how to improve request latency without making any code changes, or even seeing the code for that matter.

## Evaluating Equality Predicates with RangeBitmap

DevFeed: [Evaluating Equality Predicates with RangeBitmap](<https://devfeed.tech/articles/evaluating-equality-predicates-25641.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/range-bitmap-equality-queries>)

Author: Richard Startin's Blog

Published: 2022-12-18T00:00:00Z

Content type: article

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Library](<https://devfeed.tech/topics/library.md>), [benchmarking](<https://devfeed.tech/topics/benchmarking.md>), [data observability](<https://devfeed.tech/topics/data-observability.md>)

Tags: [benchmarking](<https://devfeed.tech/tags/benchmarking.md>), [cardinality](<https://devfeed.tech/tags/cardinality.md>), [comparison](<https://devfeed.tech/tags/comparison.md>), [data-engineering](<https://devfeed.tech/tags/data-engineering.md>), [data-structure](<https://devfeed.tech/tags/data-structure.md>), [java](<https://devfeed.tech/tags/java.md>), [library](<https://devfeed.tech/tags/library.md>), [memory](<https://devfeed.tech/tags/memory.md>), [pinot](<https://devfeed.tech/tags/pinot.md>), [range](<https://devfeed.tech/tags/range.md>), [roaring](<https://devfeed.tech/tags/roaring.md>), [speed](<https://devfeed.tech/tags/speed.md>)

### AI overview

This article evaluates equality and inequality queries using RangeBitmap in the RoaringBitmap library. It explains how the enhancement can support equality filtering as a compact inverted-index alternative, including as a fallback for Apache Pinot range indexes, and reports faster selection than a stream-based scan in the described example while using less space than some inverted indexes.

### Source excerpt

I have just implemented support for (in)equality queries against a RangeBitmap, a succinct data structure in the RoaringBitmap library which supports range queries. RangeBitmap was designed to support range queries in Apache Pinot (more details here) but this enhancement would allow a range index to be used as a fallback for (in)equality queries in case nothing better is available. Supporting (in)equality queries allows a RangeBitmap to be used as a kind of compact inverted index, trading space for time, capable of supporting high cardinality gracefully. Since RangeBitmap supports memory mapping from files, I think that it could be used for data engineering beyond Apache Pinot.

## Using JFR and JMC to root cause a performance bug in JMC caused by a typo in JFR

DevFeed: [Using JFR and JMC to root cause a performance bug in JMC caused by a typo in JFR](<https://devfeed.tech/articles/using-jfr-and-jmc-to-root-cause-a-performance-bug-in-jmc-caused-by-a-typo-in-jfr-25638.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/jmc-hanging>)

Author: Richard Startin's Blog

Published: 2022-12-18T00:00:00Z

Content type: tutorial

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [bug](<https://devfeed.tech/topics/bug.md>), [cpu](<https://devfeed.tech/topics/cpu.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [bug](<https://devfeed.tech/tags/bug.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [flamegraph](<https://devfeed.tech/tags/flamegraph.md>), [java](<https://devfeed.tech/tags/java.md>), [performance](<https://devfeed.tech/tags/performance.md>), [profiling](<https://devfeed.tech/tags/profiling.md>)

### AI overview

The article explains how overlapping events in JFR files can trigger quadratic scaling in JMC's parser, causing profiles to take a long time to load. It demonstrates profiling JMC with JFR and cautions that CPU flamegraphs alone may not distinguish slow methods from methods called too often.

### Source excerpt

When you open a profile in JMC, it normally takes a few seconds, but there are some profiles that JMC struggles to load. This happens when a profile contains events which violate an assumption made in JMC's parser: events on the same thread are almost always disjoint in their durations. When JMC parses a JFR file, it splits the events of the same type emitted on the same thread into lanes so that events within a lane are disjoint. JMC can handle overlapping events, but assumes this essentially never happens, and exhibits quadratic scaling when events overlap.

## Counting over Range Predicates

DevFeed: [Counting over Range Predicates](<https://devfeed.tech/articles/counting-over-range-predicates-25643.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/range-counts>)

Author: Richard Startin's Blog

Published: 2022-03-27T00:00:00Z

Content type: tutorial

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Streams](<https://devfeed.tech/topics/streams.md>), [Sorting](<https://devfeed.tech/topics/sorting.md>), [Benchmark](<https://devfeed.tech/topics/benchmark.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [benchmark](<https://devfeed.tech/tags/benchmark.md>), [effective](<https://devfeed.tech/tags/effective.md>), [filter](<https://devfeed.tech/tags/filter.md>), [inlining](<https://devfeed.tech/tags/inlining.md>), [java](<https://devfeed.tech/tags/java.md>), [modularity](<https://devfeed.tech/tags/modularity.md>), [performance](<https://devfeed.tech/tags/performance.md>), [roaring](<https://devfeed.tech/tags/roaring.md>), [sorting](<https://devfeed.tech/tags/sorting.md>), [streams](<https://devfeed.tech/tags/streams.md>)

### AI overview

This post examines counting objects that satisfy range and other filters when no database is available. It compares Java's Stream API with specialized Java code and finds that exploiting data already sorted by time can make filtering and counting more efficient.

### Source excerpt

This post follows on from my last post about selecting objects satisfying a range predicate, and instead looks at how to count the objects. If you can select objects, you can count them too, but it's a simpler problem so resources can be saved with a specialised solution.

## Evaluating Range Predicates

DevFeed: [Evaluating Range Predicates](<https://devfeed.tech/articles/evaluating-range-predicates-25644.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/range-predicates>)

Author: Richard Startin's Blog

Published: 2022-03-12T00:00:00Z

Content type: article

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Data analysis](<https://devfeed.tech/topics/data-analysis.md>), [Java](<https://devfeed.tech/topics/java.md>), [Sorting](<https://devfeed.tech/topics/sorting.md>), [Transactions](<https://devfeed.tech/topics/transactions.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>)

Tags: [analysis](<https://devfeed.tech/tags/analysis.md>), [data-structure](<https://devfeed.tech/tags/data-structure.md>), [java](<https://devfeed.tech/tags/java.md>), [roaring](<https://devfeed.tech/tags/roaring.md>), [sorting](<https://devfeed.tech/tags/sorting.md>), [transactions](<https://devfeed.tech/tags/transactions.md>)

### AI overview

This article examines filtering transaction data by range predicates in Java. It compares stream-based linear filtering with reordered conditions and binary search on time-sorted data, discussing branch misses and the potential benefits of indexed data structures such as RoaringBitmap.

### Source excerpt

Suppose you are doing some kind of data analysis in Java, perhaps you are analysing transactions (as in sales made). You have complex filters to evaluate before performing a calculation on Transaction objects.

## RangeBitmap - How range indexes work in Apache Pinot

DevFeed: [RangeBitmap - How range indexes work in Apache Pinot](<https://devfeed.tech/articles/rangebitmap-how-range-indexes-work-in-apache-pinot-25642.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/range-bitmap-index>)

Author: Richard Startin's Blog

Published: 2022-03-07T00:00:00Z

Content type: tutorial

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Databases](<https://devfeed.tech/topics/databases.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Routing (disambiguation)](<https://devfeed.tech/topics/routing.md>), [servers](<https://devfeed.tech/topics/servers.md>)

Tags: [apache](<https://devfeed.tech/tags/apache.md>), [data-structures](<https://devfeed.tech/tags/data-structures.md>), [databases](<https://devfeed.tech/tags/databases.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [java](<https://devfeed.tech/tags/java.md>), [pinot](<https://devfeed.tech/tags/pinot.md>), [range](<https://devfeed.tech/tags/range.md>), [roaring](<https://devfeed.tech/tags/roaring.md>), [routing](<https://devfeed.tech/tags/routing.md>), [server](<https://devfeed.tech/tags/server.md>), [servers](<https://devfeed.tech/tags/servers.md>)

### AI overview

This article explains the requirements and query-performance constraints for range indexes on unsorted numeric data in a column store such as Apache Pinot. It discusses segment-level data structures and how servers and brokers participate in pruning, routing, and result merging.

### Source excerpt

Suppose you have an unsorted array of numeric values and need to find the set of indexes of all the values which are within a range. The range predicate will be evaluated many times, so any time spent preprocessing will be amortised, and non-zero spatial overhead is expected. If the data were sorted, this would be very easy, but the indexes of the values have meaning so the data cannot be sorted. To complicate the problem slightly, the set of indexes must be produced in sorted order.

## Performance Myths and Continuous Profiling

DevFeed: [Performance Myths and Continuous Profiling](<https://devfeed.tech/articles/performance-myths-and-continuous-profiling-25640.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/perf-myths-and-continuous-profiling>)

Author: Richard Startin's Blog

Published: 2021-12-27T00:00:00Z

Content type: opinion

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [coding](<https://devfeed.tech/topics/coding.md>), [Software](<https://devfeed.tech/topics/software.md>)

Tags: [compiler](<https://devfeed.tech/tags/compiler.md>), [java](<https://devfeed.tech/tags/java.md>), [performance](<https://devfeed.tech/tags/performance.md>), [profiling](<https://devfeed.tech/tags/profiling.md>)

### AI overview

The article examines performance myths affecting Java programming, distinguishing claims that were never true from practices that were once useful. It uses examples such as increment operators and string concatenation before discussing continuous profiling as a way to evaluate performance issues.

### Source excerpt

My last post was about five very simple things you can do to avoid Java programs from being slower than they need to be. The reception to this post was mixed. Some readers agreed that the problems mentioned in the post were indeed very common, while others suggested more common inefficient patterns to avoid. For example, I could have suggested to precompile regular expressions, or not to program by exception, or to avoid String.format, but I felt this was all well covered already. The aim of the post was to help Java programmers to program defensively for efficiency - just as many do for correctness - by giving an idea of what some common things cost. However, several readers dismissed the content of the post as premature optimisation.

## 5 Mundane Java Performance Tips

DevFeed: [5 Mundane Java Performance Tips](<https://devfeed.tech/articles/5-mundane-java-performance-tips-25636.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/5-java-mundane-performance-tricks>)

Author: Richard Startin's Blog

Published: 2021-11-28T00:00:00Z

Content type: tutorial

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Software](<https://devfeed.tech/topics/software.md>), [Benchmark](<https://devfeed.tech/topics/benchmark.md>)

Tags: [benchmark](<https://devfeed.tech/tags/benchmark.md>), [code](<https://devfeed.tech/tags/code.md>), [java](<https://devfeed.tech/tags/java.md>), [performance](<https://devfeed.tech/tags/performance.md>), [software](<https://devfeed.tech/tags/software.md>), [tips](<https://devfeed.tech/tags/tips.md>)

### AI overview

This article presents five practical tips for avoiding unnecessary performance slowdowns in Java software. It emphasizes measuring real bottlenecks before optimizing and explains how sizing HashMaps appropriately can avoid costly resizes.

### Source excerpt

Most of the time it isn't really necessary to optimise software, but this post contains 5 tips to avoid making software written in Java slower for the sake of it.

## Loop Fission

DevFeed: [Loop Fission](<https://devfeed.tech/articles/loop-fission-25639.md>)

Original publisher: [Read original article](<https://richardstartin.github.io/posts/loop-fission>)

Author: Richard Startin's Blog

Published: 2021-11-27T00:00:00Z

Content type: tutorial

Language: en

Sources: [Richard Startin's Blog](<https://devfeed.tech/sources/richard-startin-s-blog.md>)

Topics: [Compiler](<https://devfeed.tech/topics/compiler.md>), [JIT](<https://devfeed.tech/topics/jit.md>), [Benchmark](<https://devfeed.tech/topics/benchmark.md>), [Code generation](<https://devfeed.tech/topics/code-generation.md>), [Caching](<https://devfeed.tech/topics/caching.md>), [C++](<https://devfeed.tech/topics/c-plus-plus.md>)

Tags: [benchmark](<https://devfeed.tech/tags/benchmark.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [cache](<https://devfeed.tech/tags/cache.md>), [code-generation](<https://devfeed.tech/tags/code-generation.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [examples](<https://devfeed.tech/tags/examples.md>), [java](<https://devfeed.tech/tags/java.md>), [jit](<https://devfeed.tech/tags/jit.md>), [performance](<https://devfeed.tech/tags/performance.md>)

### AI overview

This article explains loop fission, the practice of splitting a loop that performs multiple tasks into separate loops. Using bitmap XOR and counting examples, it describes how loop fission can improve performance through compiler optimizations such as autovectorization, while noting that fused loops may sometimes benefit from better cache use. It also compares behavior in HotSpot C2 and clang.

### Source excerpt

Loop fission is a process normally applied by a compiler to loops to make them faster. The idea is to split larger loop bodies which perform several distinct tasks into separate loops, in the hope that the individual loops can be optimised more effectively in isolation. As far as I'm aware, C2, Hotspot's JIT compiler, doesn't do this so you have to do it yourself. I came across a couple of cases where this was profitable recently, and this post uses these as examples.