C vs Rust vs Zig for Native Codes

If we do really need to going as low as we can for building hardware driver, system component or high performance and low latency engine. We need to use native code. Even if C# has the same capabilities, still that's not ready yet for that part. Golang also not ready because it's has runtime, even it's small we can't fully control the GC and also the Go routine and scheduler.


Why do we need driver today?


The answer is cloud. A lot of cloud provider give us a cool advantaged cheap access to great hardware. One of this is AWS Graviton2. You can access Nitro cards for networking using DPDK and bypassing kernel altogether. As we all know that kernel or system call is very expensive as it's involved a lot of ceremony and layering. To leverage that you need to use native language that compiled directly to the metal.


So what do we have? C++ ?


C++ is very bloated language, too many features, different style, new standard every year and kind of confusing to create a simple stuff and get jobs done. This is something that game developers and finance really used to. However for new code i'm not sure that we should go C++, as it's very complex language. Easy to create error prone code.


What we left then? How bout Rust?


Rust is the new sexy in the block for native code. It's works nice with their borrowing mechanism, the compiler is your friends (well, sometimes it get grumpy, but for good) But as i mention before it's nice language with empty space. Small tooling, IDE is not that great. Debugger and Profiler is nearly empty. We also lack of support for production issues and tracing/instrumentation. I like the language however it's kinda difficult as investment for now


Zig?


Still this one is great but the tooling is very lacking event compare with Rust. Rust community also big and they already have Rust Foundation that backed by the like of microsoft, amazon, google etc. We don't have any in Zig. It's decentralized and kind of scary.


Zig is pretty, as it bring what best from Go, Managed and C itself. We have exception handling. We also have defer from Go. We also have total control of memory allocation layout and it works nicely with existing C library.


But. It's empty.... it doesn't even have a proper websocket library now. The networking stack is depends largely on existing C interoperability.


Let us C clearly...


So back to the basic, C programming has been there a long time. So many library that has been well tested. The driver is really good fit for C. The tooling is improving also not as good as managed language. To be honest, the language is simple and give you all the control you need.


About memory safety and everything, we need to follow the good coding practice and also keep the testing and profiler closer. As it will give us confidence on what will be the runtime looks like.


If you see the code from late Pieter Hintjens, you will change your mind about C. See his explanation about Scalable C


mlm_client_t *writer = mlm_client_new ();

mlm_client_set_plain_auth (writer, "writer", "secret");
mlm_client_connect (writer, "tcp://127.0.0.1:9999", 1000, "writer");
mlm_client_set_producer (writer, "weather");

mlm_client_sendx (writer, "temp.moscow", "10", NULL);
mlm_client_sendx (writer, "temp.london", "15", NULL);
mlm_client_sendx (writer, "temp.madrid", "32", NULL);

mlm_client_destroy (&writer);

looks like OO to me..


if you see the zeromq codes, you can see how beautiful C looks like.


//  Hello World client
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

int main (void)
{
    printf ("Connecting to hello world server...\n");
    
    void *context = zmq_ctx_new ();
    void *requester = zmq_socket (context, ZMQ_REQ);
    
    zmq_connect (requester, "tcp://localhost:5555");

    int request_nbr;
    for (request_nbr = 0; request_nbr != 10; request_nbr++) 
    {
        char buffer [10];
        printf ("Sending Hello %d...\n", request_nbr);
        
        zmq_send (requester, "Hello", 5, 0);
        zmq_recv (requester, buffer, 10, 0);
        
        printf ("Received World %d\n", request_nbr);
    }
    
    zmq_close (requester);
    zmq_ctx_destroy (context);
    
    return 0;
}

I think you change your mind. But remember this C one only for low level stuff like creating driver, system programming and high perf access to hardware. Don't create CRUD or REST API with this one. You will got nothing but blood in your hand.


Remember Old doesn't mean Ugly. It's our thinking and typing ability to produce great code in term of correctness, efficiency and readability. Programmer that has a good taste is programmer that can pursue a great things.


We don't want to die with our own software because of glitch or malfunction right?


Cheers

96 views0 comments

Recent Posts

See All

Lately i'm doing work on crypto financial industry and creating a bunch of connectors to each exchange using websocket and http rest api. Finally i realize that we need to reconsider why we are using