Thursday, October 14, 2021

Slovenian Delphi 11 Webinar

Just a short notice for Slovenian readers - In case you missed it, next week you'll be able to join a Slovenian webinar about Delphi 11. 

Register here

Wednesday, February 10, 2021

Readers-writer lock - Part 4: Improving TLightweightMREW

While the TLightweightMREW is quite handy, it is not perfect. There's a weird assymmetry in it. On all operating systems that Delphi can compile for, read locks are reentrant (recursive) while write locks are not. In other words, if a thread already owns a read lock, it can call BeginRead again and it will succeed. Write locks are different. If a thread already owns a write lock and calls BeginWrite again, it will either deadlock (on Windows) or raise an exception (on other supported platforms).

This is, however, relatively simple to fix. I have implemented a simple wrapper for the TLightweightMREW lock in TLightweightMREWEx. This new record uses internal TLightweightMREW to provide locking and adds some simple logic to implement write lock reentrancy. The implementation and accompanying test program rwReentrantWriter can be found at

Monday, February 08, 2021

Readers-writer lock - Part 3: Some numbers

In order to convince you that a readers-writer lock is not a stupid idea, I should finally show some numbers. In this article I'll present a minimalistic (but still real-life) example which allows us to compare different locking solutions.

All code from this article is available in project rwLock at

Tuesday, December 08, 2020

Readers-writer lock - Part 2: Implementation

In the previous installment I introduced the idea of a readers-writer lock. Today I'll look into readers-writer lock implementations (yes, multiple) that are available in the Delphi run-time library.

Sunday, November 08, 2020

Readers-writer lock - Part 1: Why?

One of the pleasant surprises in Delphi 10.4.1 was the addition of a new readers-writer lock implementation TLightweightMREW. While it was probably not noticed by most of the users, I was quite happy to see it implemented. 

So now you are asking yourself - what is this readers-writer lock and why am I so happy to see it in Delphi? Well, I'm glad that you're asking! Let me explain ...

In multithreaded programming (as most of my horror stories start), we frequently run into a problem of resource sharing. Two threads want to modify a shared resource at the same time and that can cause many problems, from information being overwritten to corrupted data and program crashes.

To fix this, we add resource protection. Usually that is just a critical section (typically through a TCriticalSection wrapper), or Delphi's TMonitor. Sometimes, however, protecting resources with a simple critical section causes an unnecessary performance drop, and that's when a readers-writer lock (may) come into play.

Saturday, May 30, 2020

OmniThreadLibrary 3.07.8

New OmniThreadLibrary is out! Get it while it’s hot!

Version 3.07.8 is mostly a bugfix release. It fixes few small bugs and enables support for Delphi 10.4.

You can get it now on git, download the ZIP archive, install it with Delphinus or with GetIt (in few days).

For more information, visit OmniThreadLibrary home page or write your question on the forum.

Wednesday, May 27, 2020

Top three Delphi 10.4 features

Delphi 10.4 has just been released (turn here for a great overview) and has some nice enhancements even for us, die-hard Windows developers. It is too early to give any deep analysis as I have just installed it and did not do any thorough testing, but I can already pick my top three new features. In no particular order, here they are:

Friday, February 14, 2020

Long live Delphi!

Something great has happened on this day, 25 years ago.

It was the sign of Aquarius. People were listening to Creep. And the AppBuilder was released.

You don’t know AppBuilder? Sure you do! It was developed andthanks to Novell — released under codename Delphi.

Indeed, our beloved Delphi is 25 years old today! A quarter of a century!

Friday, November 29, 2019

Sales! Sales! Sales!

Parallel Programming with OmniThreadLibrary

e-book: 50% off

printed book: 25% off (use coupon BLACKFRIDAY25)

Delphi High Performance

e-book: 72% off

Hands-on Design Patterns with Delphi

e-book: 80% off

Friday, November 08, 2019

ITDevCon X

The ITDevCon X - the tenth edition! - has just ended and boy was it a blast! (As usual, I should say.)

This was my seventh ITDevCon conference and I always like to visit it. This year was no exception.

Thank you Daniele, Valentina, Fabrizio, and all bit Time gals and guys for organizing two days of great fun and great food!

P.S. My slides & code are already available online.

Monday, September 30, 2019

CompareValue for booleans

CompareValue function is incredibly practical when you are writing comparers (functions that determine how some data structure is ordered). System.Math and System.StrUtils define a bunch of functions that can be used to compare integers, doubles, strings … There’s, however, no CompareValue for booleans.

A CompareValue function compares two parameters, traditionally named left and right, and returns 0 if they are the same, –1 if left is smaller and 1 if right is smaller.

If we use the usual ordering of false < true, we can write the missing function as follows:

function CompareValue(left, right: boolean): integer; overload;
  if left < right then
    Result := -1
  else if left > right then
    Result := 1
    Result := 0;

Your task for today – if you choose to accept it – is: Write this function without any if statements.

Thursday, September 12, 2019

Visit “What’s new in Rio 10.3.2” in Ljubljana

On September 26th I’ll talk about RAD Studio Rio in Ljubljana. We’ll discuss 10.3 a bit and 10.3.1/10.3.2 updates in more detail. We’ll also look into the future to see what 10.4 might bring.

This will also be a good opportunity to see my latest book, Design patterns with Delphi, or get your own copy signed.

Participation is free, but you should register here so we can prepare enough food for everyone.

Tuesday, July 16, 2019

When True is not

Pop quiz! How can the following program …


… output this:?



Tuesday, July 02, 2019

The case of a missing begin/end

Delphi never stops surprising me …
Did you know that this is a valid syntax?
case a of
  0: Writeln(0);
This code indeed compiles and works exactly as the following fragment.
case a of
  0: Writeln(0);
  else begin
I personally would never drop begin/end inside a case/else statement, but at least someone must disagree. I found such example in a very (VERY!) old code (it was written for Delphi 2) and I was quite surprised that it compiles at all.


Anton Alisov suggested formatting first example as:
case a of
  0: Writeln(0);
I guess this makes more sense (but just an itsy bitsy teenie weenie bit more).

Thursday, June 06, 2019

Monday, April 29, 2019

Spring4D European Conference 2019 sessions

Slides and code for the Spring4D conference are now published on the conference page.

Slides and code for my two sessions – Design patterns with Spring4D and Interception and dynamic proxy – are also available on my presentations page.

Saturday, April 27, 2019

FastMM4 large memory allocation–benchmarking VirtualAlloc

Earlier this week a long-time customer asked me why FastMM allocates large memory blocks from the top of the memory and if that option could safely be turned off. Their reasoning was that such allocations are much slower than normal ones. The question surprised me as I didn’t know of any such difference in speed so I did what I usually do–I wrote a benchmark application and measured it.
TL;DR Yes, allocating from the top is slower. No, the difference is not big and in most cases you’ll not even notice it.
There were, however, other interesting results that my simple benchmark pointed out. More on that in a moment, but first…

Thursday, April 18, 2019

Books, books, books

Dear reader,

You probably know that I write books. A big part of making a book, however, is not just writing it, but letting all the potential readers out there know that the book exists. I'm doing a lot there - and so is my publisher - but still we can't reach all the potential readers ourselves.

That's where you come in!

If you have read any of my books and if you loved it and want the others to know, please consider publishing a review on the Amazon site. More reviews make Amazon algorithms treat the book with more respect and they recommend it more to customers.

Leave the review here: Delphi High Performance, Hands-on Design Patterns with Delphi.

You can also just tell your colleagues in any social circle - digital or real-life - that you like the book. Spread the word!

If you think that is too much and you don't want to get involved so deep, it doesn't matter. I still love you.

On the other hand, if you didn't like my book, let me know. I want to improve, so tell me why you don't like it and what I can do to make my next book better. My contact info is here.

Thank you,


Monday, April 08, 2019

Deep Dive into Design Patterns

Hands-On Design Patterns with Delphi Book CoverWhile writing Design Patterns with Delphi, I spent quite some time researching existing literature on design patterns implementation in Delphi, design patterns in other languages, other types of patterns, design principles and so on …

In case you would like to dig deeper than the book takes you, here is my reading list.

Tuesday, March 26, 2019

Spring conference, spring edition

Hurry up, you only have five (5) days left to get a Spring4D European Conference ticket at the regular price!

Spring 4D Logo

It’s gonna be a blast! Stefan will be there, of course (can you imagine Spring 4D without him in the picture?), and so will be I. There will be a ton of interesting sessions, and lots of time for eye-to-eye discussions. Marco has announced his presence, I’ll be bringing my books (or you can bring your own copy, if you already own it and want it signed), Stefan will be accepting musical requests (not really ;) ) …

You can join us for a day or two. Your call, but I would certainly recommend the latter, because this conference will ROCK!

“Bee there Orr Bee A Rectangular Thyng
- The Band With Rocks In *

Friday, March 08, 2019

Delphi developer needed (Slovenia)

Slovenian company BASS is looking for a Delphi developer (on-site in Celje, Slovenia).

(I’m not affiliated with them; they just asked me to spread a word around. If you have any questions, contact them directly.)

Wednesday, February 27, 2019

Design Patterns with Delphi (book)

Hurrah, hurray, my third book is here! It’s called Hands-On Design Patterns with Delphi and (just like my first book) I wrote it for Packt Publishing. (The second book was self-published and I expect the fourth one to be, too.)

As the name says, “Design Patterns with Delphi” deals with design patterns. It is a bit different from most of design pattern books and websites you will find on the Internet. Case in point A: There are no UML diagrams. I don‘t speak UML. Tried to learn it few times but for some reason the whole concept doesn‘t agree with me. If you like diagrams, don’t fear though. Any book on design patterns - and most websites covering that topic - will gladly show how any design pattern can be diagrammed. That, however, is not important and should not govern your decision to buy the book.

More important is case in point B: This book speaks Delphi. All the examples are written in Delphi and language features are used to the full. I also covered few less known Delphi idioms in separate sections. You’ll still be able to follow the discussion even though you may program in a different Pascal dialect.

There’s also case in point C: Examples make sense. I deeply dislike classical design pattern examples of the “And then we want to write this program for different toolkits and it should also be able to draw circles, not only squares” kind. Euch! I tried to find a good example for each design pattern. Admittedly, I ended with few examples that draw triangles and squares on screen (mostly because some patterns were designed specifically for solving such problems), but most of them are of a more practical nature.

This book covers all three classical design pattern categories - Creational patterns, Structural patterns, and Behavioral patterns. It also discusses patterns from the newer Concurrency patterns category. At the end I threw in some borderline-pattern(ish) topics and ended with a discussion of few patterns that cannot be strictly classified as “design” patterns.

In this book you’ll find:

  • Chapter 1

    An introduction to patterns. Exploration of design principles, design patterns, and idioms. A mention of anti-patterns. A short description of most important design principles. Delphi idioms: creating and destroying objects.
  • Chapter 2

    Creation patterns part 1. Singleton. Dependency injection. Lazy initialization. Object pool.
  • Chapter 3

    Creation patterns part 2. Factory method, Abstract factory, Prototype, Builder. Delphi idioms: Assign and AssignTo.
  • Chapter 4

    Structural patterns part 1. Composite. Flyweight. Marker interface. Bridge. Delphi idioms: comparers and hashers.
  • Chapter 5

    Structure patterns part 2. Adapter. Proxy. Decorator. Facade. Delphi idioms: replacing components in runtime. Also: helpers.
  • Chapter 6

    Behavioral patterns part 1. Null object. Template method. Command. State.
  • Chapter 7

    Behavioral patterns part 2. Iterator. Visitor. Observer. Memento. Delphi idioms: for .. in.
  • Chapter 8

    Concurrency patterns part 1. Locking. Lock striping. Double-checked locking. Optimistic locking. Readers-writers lock. Delphi idioms: tasks and threads. Also: bitwise operators.
  • Chapter 9

    Concurrency patterns part 2. Thread pool. Messaging. Future. Pipeline.
  • Chapter 10

    Writing Delphi programs. Event-driven programming. Actions. LiveBindings. Form inheritance. Frames. Data modules.
  • Chapter 11

    Wrapping it up. Exceptions. Debugging. Functional programming.

I hope you will like this book and learn a lot from it. I know I did during the nine months I spent writing it. And if you find any bug in the code, let me know so I can correct it in the second release!

Saturday, February 23, 2019

OmniThreadLibrary 3.07.7

New OmniThreadLibrary is out! Get it while it’s hot!

Version 3.07.7 is mostly a bugfix release. It fixes a stupid mistake introduced in version 3.07.6 plus some other minor bugs.

You can get it now on git, download the ZIP archive, install it with Delphinus or with GetIt.

For more information, visit OmniThreadLibrary home page or write your question on the forum.

Tuesday, January 29, 2019

Caching with class variables

Recently I was extending a swiss-army-knife helper record we are using at work and I noticed a small piece of suboptimal code. At first I let it be as I couldn’t think of a simple way of improving the code – and the problem was really not so big that it should be fixed with a complicated solution. At some point, however, a simple and elegant solution appeared to me and I like it so much that I want to share it with the world ;)

Tuesday, November 27, 2018

RAD Studio 10.3 Rio in Slovenia

On December, 6th I’ll be showing all that is new and shiny in 10.3 Rio to anyone that happens to pass by!

Join me in Ljubljana at 9:30 in the “standard” venue … just don’t forget to register first.

Monday, November 26, 2018

OmniThreadLibrary 3.07.6

Hear, hear, new OmniThreadLibrary is here!
Version 3.07.6 brings official support for Delphi 10.3 Rio, few changes and bugfixes.
You can get it now on git, download the ZIP archive, install it with Delphinus or with GetIt.
For more information, visit OmniThreadLibrary home page or write your question on the forum.

Tuesday, November 20, 2018 in Delphi!

Today I was porting some legacy code and noticed a weird warning:


Weird warning, I thought. Obviously the loop variable can be passed as a var parameter as the code compiles. Why a warning and not an error, then?

Thursday, November 08, 2018

Using configuration records and operators to reduce number of overloaded methods

When writing libraries you sometimes want to provide users (that is, programmers) with a flexible API. If a specific part of your library can be used in different ways, you may want to provide multiple overloaded methods accepting different combinations of parameters.

For example, IOmniPipeline interface from OmniThreadLibrary implements three overloaded Stage functions.

function  Stage(pipelineStage: TPipelineSimpleStageDelegate; 
taskConfig: IOmniTaskConfig = nil): IOmniPipeline; overload;
function  Stage(pipelineStage: TPipelineStageDelegate; 
taskConfig: IOmniTaskConfig = nil): IOmniPipeline; overload;
function  Stage(pipelineStage: TPipelineStageDelegateEx; 
taskConfig: IOmniTaskConfig = nil): IOmniPipeline; overload;

Delphi’s own System.Threading is even worse. In class TParallel, for example, there are 32 overloads of the &For class function. Thirty two! Not only it is hard to select appropriate function; it is also hard to decode something useful from the code completion tip. Check the image below – can you tell which overloaded version I’m trying to call? Me neither!


Because of all that, it is usually good to minimize number of overloaded methods. We can do some work by adding default parameters, but sometimes this doesn’t help. Today I’d like to present an alternative solution – configuration records and operator overloading. To simplify things, I’ll present a mostly made-up problem. You can download it from github.

Wednesday, June 20, 2018

Delphi - always full of surprises!

After all these years, Delphi still surprises me. Apparently, as I found out today (by making a stupid typo), Copy(string, index, count) doesn't require the count parameter!

IOW, following two lines do exactly the same:

s := Copy('123456789', 4, 6);
s := Copy('123456789', 4);

Works for arrays, too!

Of course, this is not documented.

See for yourself:

program ProjectCopy;


{$R *.res}


  s1: TArray;

  Writeln(Copy('123456789', 4, 6));
  Writeln(Copy('123456789', 4));
  s1 := ['1', '2', '3'];
  Writeln(string.Join(',', Copy(s1, 1, 2)));
  Writeln(string.Join(',', Copy(s1, 1)));

This code outputs (in Tokyo):


I'd suspect that this goes waaaaaay back. I tested string version with XE2 and it works the same as in Tokyo.

Sunday, May 20, 2018

Introducing MultiBuilder

When I'm working on OmniThreadLibrary, I have to keep backwards compatibility in mind. And man, is that hard! OmniThreadLibrary supports every Delphi from 2007 onward and that means lots of IFDEFs and some ugly hacks.

Typically I develop new stuff on Berlin or Tokyo and then occasionally start a batch script that tests if everything compiles and runs unit tests for all supported platforms in parallel. (I wrote about that system two years ago in article Setting Up a Parallel Build System.) Dealing with 14 DOS windows, each showing compilation log, is cumbersome, though, and that's why I do this step entirely too infrequently.

For quite some time I wanted to write a simple framework that would put my homebrew build batch into a more formal framework and which would display compilation results in a nicer way. Well, this weekend I had some time and I sat down and put together just that - a MultiBuilder. I can promise that it will be extensively used in development of OmniThreadLibrary v4. (Which, incidentally, will drop support for 2007 to XE. You've been notified.)

The rest of this post represents a short documentation for the project, taken from its GitHub page.

I don't plan to spend much time on this project. If you find it useful and if you would like to make it better, go ahead! Make the changes, create a pull request. I'll be very happy to consider all improvements.

Monday, May 14, 2018

See you in Piacenza!

It is now official - I'll be participating both as a seminar and as a conference speaker on Delphi Day 2018 in Piacenza. This is a new experience for me - I had quite some presentations in Italy so far and I know that Italians are both great participants and excellent hosts, but I was never part of Delphi Day.

On June, 6th I'll lead a seminar titled Writing High Performance Delphi Applications. It will be based on material from my Delphi High Performance book. We will look into variety of topics - algorithmic complexity, performance considerations when using built-in Delphi types, memory manager internals and optimisations and parallel programming. This will also be a good chance to grab a signed copy of the "high performance" and Parallel Programming with OmniThreadLibrary books (wink, wink ;) ).

Next day I'll participate on the conference programme with a talk called Defensive programming for a better future. Without even starting Delphi (look ma, no hands!) I'll look into different areas of programming where some common sense and simple guidelines can represent a difference between well- functioning code and a nest of bugs.

See you!