Copy, Paste and Edit Java to C# after 20 years
This post is part of C# Advent Calendar 2023. Visit it for all the awesome upcoming posts!
C# and .NET have an awesome ecosystem, with tons of libraries and code snippets out there.
But sometimes you get that rare snippet of code in another language. In this blog post, we copy, paste, and edit some example snippets from Java languages to C#. When C# started back in 2001, Java and C# were similar languages. But in the last 20 years, C# has quickly evolved in its unique way. So, let’s if that similarity still helps you:
Java: Native Memory Handling is Getting Easier
JDK 19, 20, 21 has a new preview API called 'Foreign Function & Memory API' that makes interacting with native memory and native libraries way easier. Before you had to use JNI, JNA or JNR to interact with native libraries.
Further, interacting with 'native' memory was clunky. You either used ByteBuffers,
which have a clunky/dated API, max addressable size 2GByte plus 'freeing' relying on
the GC, unless you do ugly reflection hacks. Or you went down the Unsafe
route.
Anyway, if your projects allows, I would heavily recommend to the new APIs. If it is a project you deploy in your backend, you can control the JDK. If it is a new library, I would still think about starting/consider the new APIs, so that the library can be kick ass by the time it is mature.
Mysterious Hanging Java Process
I recently had a Java (Bamboo Dev Instance) app just hanging when it started up. Since it was a dev setup, which sometimes has other issues, I did the usual things, like:
Turn it on and off again, aka restart it.
Clean up the working directory, like a
mvn clean
,make clean
or what ever.Check out a stable branch.
Run against different sets of dependency versions
The app kept on being stuck. So, I was forced to debug it =).
Test Containers for C#/.NET
This post is part of C# Advent Calendar 2022.
Many applications lean heavily on relation database. Your application uses complex queries, constrains on data and all more of the wonderful features of a relation database. That means that a lot of your applications behavior depends on how the database acts.
Therefore, I try to test an against actual database system.
Years ago this used to be a challenge, as most database systems where hard to setup and automate.
Today it is easy.
Use TestContainers!
Test Containers
TestContainers is a library which starts up Docker containers for your tests. More, it provides many pre-configured setups for databases.
Redis Clone: Reducing Memory Pressure
After the taking a look at the original naive implementation, I wanted to try reducing the memory churn. By accident the IO optimizations already reduced the memory usage. Let’s go a bit further, trimming down some memory usage.
I often look out for two things: - Object allocations of objects which are immediately thrown away again. Yes, the JVM allocator and GC do an amazing job handling short-lived objects. However, it’s not magic and the memory bandwidth is limited. So, removing unnecessary short-lived objects is often easy and gives you more memory bandwidth headroom. - Ensuring long-lived objects are in a compact form and a useful format for the purpose.
Anyway, I’m trying to shave off some allocations in this blog post. Note, as I reduce allocations the code becomes less Java-y and I introduce C-like fragility, where life-time of memory matters. In a real-world app I would only use such optimizations only if you really need more performance.