Question

I have some Ruby code that interacts with a C application. Right now, it spawns the executable using the Kernel#system method each time it needs to pass data to the application. What are the advantages/disadvantages system-side with this approach versus creating a Ruby C extension.

Was it helpful?

Solution

Kernel#system

Advantages

Calling native code through Kernel#system is the simplest option to implement, and therefore the fastest to code. It's also flexible -- you can easily call not only C code, but executables of any other language: shell scripts, Python, what have you.

Disadvantages

Using system involves a relatively large amount of overhead: it forks your Ruby interpreter process, execs a subshell, invokes the C application, and then waits for the child process to exit. All of these are fairly costly in terms of time and system resources, especially if you're doing it in a tight loop.

C extensions

Advantages

Interfacing with native code by writing a C extension gets you blazing speed and low overhead. It also gives you a great deal more flexibility in terms of sending data to and from C-land; with system, you need to be able to serialize the child application's inputs through command-line arguments (and you need to use either backticks or pipes to collect its output), but when you're writing an extension you can just pass Ruby objects in and out, which lets you construct a more natural API.

Disadvantages

C extensions are a lot more work to write, build, and distribute properly. Also, if you mess up in C-land, you'll often crash your interpreter instead of throwing an exception, which is harder to debug. Unless you're careful, you're also likely to bind yourself to the platform you're writing on, which hurts portability.

Summary

Really, the best guidance is to start simple, and add the complexities of C extensions where it's actually measurably beneficial (read: after benchmarking).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top