Quite Simple Memory Pool in C#

This article shows a quite simple memory pool to make a thread-unsafe library thread-safe without performance degradation in single-threaded programs. Same as the previous article, this article is about DynaJson.

Thread-safety requires overhead to allocate an instance by each invocation to isolate data being altered. Unless thread-safety is required, we can use a static class or a singleton to eliminate any additional allocation.

When I made DynaJson thread-safe, I adopted a memory pool to avoid the allocations in single-threaded programs. When a program start, DynaJson allocates one instance in the memory pool. In single-threaded programs, DynaJson repeatedly rents and returns the instance from/to the pool. In multi-threaded programs, DynaJson allocates additional instances only when more than one thread uses DynaJson at the same time because the memory pool gets empty.

As for a memory pool, there is an implementation on the .NET platform, that is, MemoryPool<T>. But .NET Standard 2.0, an API set that DynaJson uses, doesn't have the class. So I originally implemented a memory pool.

In implementing a memory pool, we need to care how the speed of the operations gets much faster than the allocations. We mainly use locks to implement thread-safe data structures. But locks are slower than the allocations, so we must implement a memory pool in a lock-free way.

In C#, most implementations of lock-free data structures use Interlocked.CompareExchange. This article shows a lock-free stack implemented with the method. I implemented the following quite simple memory pool referring to the stack.

I have to say this is a poor implementation because it causes another allocation whenever an application returns an instance. Nevertheless, the size of the allocated instance is only 16 bytes, so that this memory pool can reduce the overall cost of the allocations in DynaJson.

The following graph compares the times to parse a simple JSON {"X":1234.5,"Y":5.6789,"Name":"Sakura"} without and with the memory pool. The memory pool reduces the processing time by 203 ns.

[Unity] How to Use Physics.OverlapCapsule

Capsule and Cube Collider

You can use Physics.OverlapCapsule to get two Colliders overlapped with a CapsulCollider as above. This method takes the position and the size of a capsule and returns all Colliders overlapped by the capsule.

You can get the Colliders by configuring a Kinematic Rigidbody Trigger Collier and handling the OnTriggerEnter message, but the method is handy.

Continue reading "[Unity] How to Use Physics.OverlapCapsule"

How to Make JSON Parser Strict

I developed a JSON Parser for C# named DynaJson. It is very strict to the standard of RFC 8259. It accepts all conformant and rejects all non-conformant JSONs except for two exceptions.

One exception is trailing-commas. Another is leading 0 in numbers, for example, 02 and -02. The former is for practicality. The latter is for compatibility with DynamicJson.

JSON's grammar is simple, but carelessly implemented parsers don't accept all conformant and not reject non-conformant JSONs. An excellent article of Parsing JSON is a Minefield shows where mines are in implementing JSON parsers.

Continue reading "How to Make JSON Parser Strict"

Mount Any Windows Folder into Containers on Docker for Windows

In a native Docker environment, you can mount /source in a container host onto /destination in a container by docker run -v /source:/destination and access it from the container.

Well then, how can you mount C:\Source in Windows onto /destination in a container on Docker for Windows? You can't directly mount C:\Source in the VM host into the container, of course.

As the first step, you have to set up C:\Source as a shared folder for a VM when you create it with docker-machine. You can specify the shared folder with the --virtualbox-share-folder option of the VirtualBox deriver as follows.

docker-machine create --driver virtualbox --virtualbox-share-folder=C:\Source:Source

Continue reading "Mount Any Windows Folder into Containers on Docker for Windows"