RSSAmplifier

Blog

John Z. Li’s Programming Corner

When I learn a thing or two about programming and I feel like writing it down, I might also post it here.

/RSS feed ↗10 posts

Latest posts

Fast market data retrieval in low-latency trading systems

A market data module is necessary for any trading system. For low-latency trading systems, this is often done with multi-threading on a concurrent hash table, with a dedicated market data thread responsible for receiving, parsing and updating market data in the hash table, and another trading thread acting as a reader who retrieves market data from the hash table. While this approach definitely…

std::initilizer_list, a wasted opportunity for C++

Arrays have well-known issues in C++. Most of them are caused by the fact that arrays decay into pointers when passed as function parameters, and automatically convert to pointers in assignments. We can’t fix this without breaking a lot of existing code. Yet, even without breaking backward compatibility, the comunity once had a chance to fix it. Unfortunately, instead of fixing the real issue,…

Using C++ exceptions with Lua

When calling C/C++ code from Lua, consider the following cases regarding control flow: Lua calls C/C++ code, and there is an error in C/C++ code. Lua calls C/C++ code, and C/C== code calls Lua code, and there is an error inside the called Lua code. A Lua coroutine calls C/C++ code, and inside C/C++ code the coroutine yields. A Lua coroutine calls C/C++ code, and C/C++ code calls another Lua…

Processing files that are too big to fit into memory

Someone shared an interview question he got asked during a programming skills interview session the other day. The question is like this There is this production system, it splits out metadata about each client request into a csv file. At the end of each day, the file needs to be processed to remove duplicate lines as part of pre-processing steps. But the file is very large with its size exceeding…

Two dimensional hash tables for low latency trading systems

It is well-known that, in order sto make a trading system low-latency, one needs to optimize its memory access pattern. Not only that more hash-table looking-up would add extra latency, but also, maybe more importantly, memory locality is crucial to reduce cache miss. The more we keep hot data in a small-sized piece of memory, the more likely, when CPU needs data, the data is hot (living in near…

Configurable configuration files

Any nontrivial piece of software would require some kind of configuration, usually by loading a configuration file in program starting up. But what is a configuration file exactly? A configuration file contains information that is part of the initial state of the program. There are two sides of a configuration file: data that is contained in the file, and how the data gets mapped into program…

Use Vim as git diff and merge tool

When working on remote servers, GUI-based diff and merge tools are uaually a luxury we cannot afford. In such a situation, vim is often what we can rely on, because it is installed by default by almost all distributions. It is useful to learn how to do git diff and git merge from terminal with only vim. Configuration Put the following in .bashrc, so that vimdiff always uses the vim found in $PATH,…

Daisy chain wiring of functions of no return

Assuming you are working on a toy trading system, it consists of the following modules: A client order validation module (let us call it RequestValidator); A risk check module (let us call it RiskChecker); A order book module to do book-keeping (let us call it OrderBook); An Exchange session management module which translates an order into Exchange format and send it to Exchange (let us call it…

Boost::split is broken

Several days ago, I was bitten by this weird behavior of boost::split: if the input string is empty, it puts an empty string into the output vector. With the following code, the result vector is not empty but contains an empty string. std::vector<std::string> result; boost::split(result, "", boost::is_any_of(","), boost::algorithm::token_compress_on); assert(result.size() == 1u); This is really…

How memory mapped file with ftruancate might cause SIGBUS on Linux

When memory-mapped files are used on Linux systems, once typical usage pattern is to start with an newly created empty file or a small sized one, and then to enlarge the file size using ftruncate to allocate some file space, so that the application, after the file being mapped memory, can append data to the file.