On why RavenDB is written in C#
Greg Young has an interesting reply to my post here. I’m going to reply to it here.
RavenDB nor EventStore should be written in C#.
That may be true for the EventStore, but it isn’t true for RavenDB. Being able to work with the .NET framework makes for a lot of things a lot simpler. Let us take a simple example, every day, I have to clear the unused auto indexes, but only if there has been queries to the collection in question. In C#, here is the code to give me the last query time for all collections in the database:
No, if we wanted to do this in C, as the go to example for system level programming, I would need to select which hash function to use. RavenDB being a non trivial project, I’ll probably have one, for simplicity sake, I selected this one, which gives us the following:
I’ve elided all error handling code, and I’ve introduced a silent potential “use after free” memory issue.
This is something that runs one a day, but the amount of code, effort and potential things to manage is quite a lot, compare to the simplicity we get in C#.
Now, this is somewhat of a straw man’s argument. Because the code would be much simpler in C++ or in Go (no idea about Rust, I’m afraid), but it demonstrate the disparity between the two options.
But Greg isn’t actually talking about code.
A different environment such as C/C++/Go/Rust would be far superior to haven been written in C#. Cross compiling C# is a pain in the ass to say the least whether we talk about supporting linux via mono or .netcore, both are very immature solutions compared to the alternatives. The amount of time saved by writing C# code is lost on the debugging of issues and having unusual viewpoints of them. The amount of time saved by writing in C# is completely lost from an operational perspective of having something that is not-so-standard. We have not yet talked about the amount of time spent in dealing with things like packaging for 5+ package managers and making things idiomatic for varying distributions.
I have one statement in response to this. Mono sucks, a lot.
I suspect that a lot of Greg’s pain has been involved directly with Mono. And while I have some frustrations with .NET Core, I don’t agree with lumping it together with Mono. And Greg’s very market was primarily Linux admins. While I would love to that be a major market for us, we see a lot more usage in Windows and Enterprise shops. The rules seems to be simpler there. I can deploy the .NET Core along with my application, no separate install necessary, so that makes it easier. What we have found customers want is docker instances so they can just throw RavenDB up there and be happy.
A lot of the pain Greg has experienced isn’t relevant any longer.
What is more, he keep considering just the core product. There are quite a lot of additional things that needs to happen to take a project to a product. Some of this is external (documentation, for example) and some of this is internal (high level of management studio, good monitoring and debugging, etc). I have seen what “system level guys” typically consider sufficient into itself in those regards. Thank you, but no.
A lot of our time is actually invested in making sure the whole thing is better, spreading oil over the machinery, and the more lightweight and easy we can make it, the better.
Core CLR is now one of the best platforms exists, C# with cross platform. the past isn't relevant for today.
If C# was not available, I would use C++/QT. You get a lot of simple containers if you do not want to work with STL. QT works cross platform.
Interesting to follow Core CLR in the future. The license wall has moved but I think it still exists somewhere.
I do not know how important it is that RavenDB works on *x-OS. There should be enough Windows servers to make a living.
I do not know how many collections you have in your database. Maybe you need an index on LastQueryTime.
You should be careful cleaning autoindex every day. Maybe you need the index every day which you just deleted. From the ERP-world I know of activating an index the night before e.g. monthly accounting.
Would be very interesting to see a comparison about what deployment, performance, and correctness is like for NetFx, CoreCLR/FX, and Mono comparatively.
You can do things much simple in C++11/14. Here is a complete runnable example. https://ideone.com/cUQyRi (I tried to paste the code here but could not figure out formatting).
Notice that the get_last_query function is not that much more longer than C#, and probably less complicated.
Also notice how Index is not a pointer. In C++, I would probably make index use movable value semantics, and instead of placing a null pointer in the database.indexes, I would just place an empty index there.
Small offtop (sorry for that), but what font do you use? Looks very nice!
Am I the only one who thinks C variant is much more clean compared to dense C#/Linq code dump?
@exim Basically... yes
Carsten, A very big db is going to have a hundred or so collection, and low hundreds of indexes. The cost of adding an index here is not worth it. And we are cleaning auto indexes that hasn't been touched in 24 hours but other indexes in the same collection where. This is actually a bit more complex, because there is a histogram, but that is the idea
Richard, On .NET - this is pure gravy, everything works, the tools are solid, pure fun. On CoreCLR - mostly working tools, need to rely on the cli more, but can work on Linux. Pretty much the same experience as full .NET, with some frustrations here are there. On Mono - nothing works, you don't know why, you pay consultants to figure out, realize it is a Mono bug, more on, rinse, repeat
Chris, Whatever is used by Sublime Text
JRB, I said that I was intentionally setting a straw man in C. However, things to note. Your C++ version isn't safe for multi threaded usage, this make things like iterating over the list while it changes very hard. Especially with regards to not leaking memory.
This is the long answer. The short would be: bullshit.
I did not suggest that all tooling should also be written in C
Your example has a few issues with it. First the amount of garbage created in the first example. Anyone who reads your blog knows you need to have a big focus on reducing the number of allocations being made. Once you go through this process the code will look quite similar to the C code.
Beyond that we both know that the writing of such code is a very small portion of the TCO of that code.
My real issue doesn't even have much to do with mono. Its production support where you are often dealing with tools like strace/dtrace/gdb/etc and then looking at code written in C#.
The administrator bias argument is also a real one in the linux world.
That said good luck with pinning your future to windows servers. There are a ton of headwinds, windows is shedding server market share left and right.
Greg, This code runs once a day. I care a LOT more about readability and ease of use here then memory utilization. It is never in any hotspot.