Bash script vs. writing C program to call other programs - c

I have 3-5 (large-ish) programs that I need merge so that they run sequentially. Speed is important, since this is for (near) real-time applications. (If there is a better way, let me know).
Would it make more sense to write a Bash script to call these other programs or to write a C program that will most likely use fork() and/or exec()? Are the trade-offs between speed and difficulty/time spent coding in favor of one over the other? Are there other methods I should look into?
I apologize if my terminology is off or if there is not enough information. Also, please correct me so that I do not repeat the same mistakes in the future.

This is the perfect use case for bash. The overhead will be less than a millisecond, and maintenance cost is way lower than for a C program.

I suggest writing the bash script and debugging it. If the performance proves adequate, you are done. It is reasonable to expect bash on a modern system (hardware and kernel) to perform well.
Otherwise use the bash script as the specification for writing a replacement C program.

The question posed is a classic question of "what is the correct tool for the job?". Obviously, bash being a shell is designed to launch applications, scripting the launch of multiple programs is as simple as listing the programs you need on separate lines along with the required arguments. But when the question is one of speed, it is one you can only answer by asking "How fast is fast enough?"
If you currently have separate programs you can string together and they can complete the job in an acceptable amount of time, why would you ever think about re-writing them for speed? The fact that you are asking the questions shows, you are either (a) having difficulty with the time it takes for the current routines to complete, of (b) you just want to see how much faster you can make it go. We all like hot-rods right?
Are there speed advantages to be had re-writing large shell apps that are number intensive in a compiled language like C -- you bet. Many times by hundreds of percent, but is it worth the time it takes to re-write. That's something only you can answer.

Related

My idea and proof how I improved any chosen app - basic level

I have been given an assignment in my college to propose an algorithm that improves or speeds up the performance of some existing program, system, algorithm. I have to additionally prove with simulations, compare execution times, etc. that my proposed changes to the chosen program actually make some improvements, cause a performance increase, make the existing application "better", etc... Do you have any ideas?
Alternatively, I could just pick a real-life situation where a program would help and write it. I am keen that it is not complex and does not require very much time and knowledge. Thanks in advance!
A colleague suggested to me to write a garbage collector for a program written in C and time comparison that the program with the GC implemented will execute faster than the one without. (for example, this: https://www.geeksforgeeks.org/snake-game-in-c/) I don't know if I won't encounter too many problems with this.

Nussinov Parallel

I am a biologist and I am trying to study computer languages. But, when I was trying to learn about the lpthread library, it seems odd as the result was lower than the sequential version.
In fact I am still reading the Tanenbaum book. But my main focus is to learn the basics of the calculations of the secondary structure of RNAs. So I found the explanation to the nussinov algorithm in a book and did indeed implement it. But when I tried to make a parallel version I believe that I might be missing the whole point, as this is my first contact with parallel implementations.
My questions are:
1. How should I implement a data-parallelism version for this algorithm ?
2. Why is my implementation slightly slower than the sequential one?
The code is available on: https://gist.github.com/drenge/6395472 (each file is a different version parallel/sequential)
there are two ways to make a parallel version of an algorithm/program.
You study the algorithm and write the serial program. Afterwards, you start profiling the program to see where you can obtain speed gains. Those are the places where parallelism might come in handy (might, not will). I call this method the "desparate man's tool". This method is useful (!), but most of the times, the method beneath can provide better performance gains. This way of doing the optimisation method only takes programming and user experience into account.
You take the algorithm and try to figure out an other algorithm that permits parallel handling of the problem. Are there independent calculations or steps in the algorithm, are there parts of the algorithm that can be done before other parts completely finish, ... This could be called "the theoretical approach". Keep in mind that every thread has its overhead, and you don't want the overhead to be bigger than the gain you wish to obtain.
In fact, a combination of both is the best way to go (if parallelism is really necessary): first concentrate on method 2 (optimise the algorithm so that is stays scientifically correct, but can be treated in multi threading). Then look at the critical thread (can be found while profiling) and start optimising that thread.
As Kerrek SB already told: parallel programming is a very complex topic, with lots of possible pitfalls. And at the end of the road, you should ask yourself: is it worth the effort. After all: loosing weeks of study and programming time to gain some minutes is not worth your while.
On the other hand, if your program will run thousands of times, frustrating users due to long waiting times or a lack of responsiveness, than maybe, it could be useful to make a more performant version after all. But again: can't you reach the same goal by optimising a sequential version without the parallel clutter? Lot's of algorithms are of order O(exp(x)) or worse and can be reduced to O(x) or even O(log(x)).
Kind regards,
PB

How much faster is C than R in practice?

I wrote a Gibbs sampler in R and decided to port it to C to see whether it would be faster. A lot of pages I have looked at claim that C will be up to 50 times faster, but every time I have used it, it's only about five or six times faster than R. My question is: is this to be expected, or are there tricks which I am not using which would make my C code significantly faster than this (like how using vectorization speeds up code in R)? I basically took the code and rewrote it in C, replacing matrix operations with for loops and making all the variables pointers.
Also, does anyone know of good resources for C from the point of view of an R programmer? There's an excellent book called The Art of R Programming by Matloff, but it seems to be written from the perspective of someone who already knows C.
Also, the screen tends to freeze when my C code is running in the standard R GUI for Windows. It doesn't crash; it unfreezes once the code has finished running, but it stops me from doing anything else in the GUI. Does anybody know how I could avoid this? I am calling the function using .C()
Many of the existing posts have explicit examples you can run, for example Darren Wilkinson has several posts on his blog analyzing this in different languages, and later even on different hardware (eg comparing his high-end laptop to his netbook and to a Raspberry Pi). Some of his posts are
the initial (then revised) post
another later post
and there are many more on his site -- these often compare C, Java, Python and more.
Now, I also turned this into a version using Rcpp -- see this blog post. We also used the same example in a comparison between Julia, Python and R/C++ at useR this summer so you should find plenty other examples and references. MCMC is widely used, and "easy pickings" for speedups.
Given these examples, allow me to add that I disagree with the two earlier comments your question received. The speed will not be the same, it is easy to do better in an example such as this, and your C/C++ skills will mostly determines how much better.
Finally, an often overlooked aspect is that the speed of the RNG matters a lot. Running down loops and adding things up is cheap -- doing "good" draws is not, and a lot of inter-system variation comes from that too.
About the GUI freezing, you might want to call R_CheckUserInterrupt and perhaps R_ProcessEvents every now and then.
I would say C, done properly, is much faster than R.
Some easy gains you could try:
Set the compiler to optimize for more speed.
Compiling with the -march flag.
Also if you're using VS, make sure you're compiling with release options, not debug.
Your observed performance difference will depend on a number of things: the type of operations that you are doing, how you write the C code, what type of compiler-level optimizations you use, your target CPU architecture, etc etc.
You can write basic, sloppy C and get something that works and runs with decent efficiency. You can also fine-tune your code for the unique characteristics of your target CPU - perhaps invoking specialized assembly instructions - and squeeze every last drop of performance that you can out of the code. You could even write code that runs significantly slower than the R version. C gives you a lot of flexibility. The limiting factor here is how much time that you want to put into writing and optimizing the C code.
The reverse is also true (duplicate the previous paragraph here, but swap "C" and "R").
I'm not trying to sound facetious, but there's really not a straightforward answer to your question. The only way to tell how much faster your C version would be is to write the code both ways and benchmark them.

Convert Bash Script to C. Is that possible?

I found the following Bash -> C converter.
Is such a way possible to convert from bash to c?
Reason: Is C faster then BASH? I want to run something as a deamon instead of a cron job.
It is possible, the question is what are the objectives of doing so. They could be a subset of:
Speed interpreted scripts can be slower
Maintainability perhaps you have a time that has more experience with C
Flexibility the script is showing limitations on what can be achieved with reasonable effort
Integration perhaps you already have a code base that you're willing to tightly integrate with the scripts
Portability
There are also other reasons, like scalability, efficiency, and probably a lot more.
Based on the objectives of the "conversion", there are quite a few ways to achieve a C equivalent, varying the amount of code that will be "native". As an example we can consider two extremes.
On one extreme, we have a compiled C code that executes mostly as bash would, so every line of the original script would produce code equivalent to a fork/exec/wait system calls, where the changes would mostly be performing equivalents to wildcard expansion, retrieving of values from environment variables, handling synchronization of the forked processes, and also handling piping with the appropriate system call.
Notice that this "simple" conversion is already tons of work, that would probably be worse than just writting another shell interpreter. Also, it doesn't meet many of the objectives above, since portability wise, it is still probably dependent on the operating system's syscalls, and performance wise, the only gain is from initially parsing the command line.
On the other extreme, we have a complete rewrite in a more C fashion. This will replace all conditionals with C conditionals, ls, cd and rm commands into their respective system calls and possibly replacing string processing with appropriate libraries.
This might be better in achieving some of the objectives, but the cost would probably be even greater than the other way, also removing a lot of code reuse, since you'd have to implement function equivalents to simple commands.
As for a tool for automating this, I don' know of any, and if there are any they probably don't have widespread use because converting Bash to C or C to Bash isn't probably a good idea. If such need arises, it is probably a sympton of a design problem, and therefore a redesign is probably a better solution. Programming languages and Scripting Languages are different tools for different jobs, even though there are areas of intersection between what can be done with them. In general,
Don't script in C, and don't code in Bash
It is best to know how and when to use the tools you have, then to find a generic universal tool (aka. there are no such things as silver bullets).
I hope this helps a little =)
I'm sure someone has made a tool, just because they could, but I haven't seen one. If you need to run a bash script from C code, it's possible to just directly execute it via (for example) a system call:
system("if [ -f /var/log/mail ]; then echo \"you've got mail! (file)\"; fi");
Other than that, I'm not aware of an easy way to "automatically" do it. As humans we can look at the above and equate that to:
if( access( "/var/log/mail", F_OK ) != -1 )
printf("you've got mail! (file)");
As one of a dozen ways that could be achieved. So it's pretty easy to do that by hand, obviously it's going to take a lot more effort to make, what can be thought of as a bash->C compiler to do it automatically.
So is it possible? Sure!
Example? Sorry, no.
There's a program I use to obfuscate code when I need that.
For some of the programs I've used it on, it does improve the speed, on others it slows the script down, but that's not why i use it. The main utility for me is that the binary is not capable of being changed or read by casual users.
article: here http://www.linux-magazine.com/Online/Features/SHC-Shell-Compiler
developer's site here: http://www.datsi.fi.upm.es/~frosal/sources/
As mentioned on one of those pages, it falls someplace between a gadget and an actual tool.

Higher level languages with C functions

Maybe this has been asked before, but I couldn't find it. My question is simple: Does it make sense to write an application in higher level languages (Java, C#, Python) and time/performance-critical functions in C? Or at this point unless you do very low level OS/game/sensor programming it is all the same to have a full, say, Java application?
It makes sense if you a) notice a performance issue, AND b) use performance measurements to locate where the problem occurs, AND c) can't achieve the desired performance by modifying the existing code.
If any of these items don't apply, then it's probably premature optimization.
If you are fluent and productive in a higher level language such a Python and Lua, then by all means start writing in that language. Look for bottlenecks if and when they exist.
speed can be quite similar with things like C#.
What is tricky is latency. So if you want to write something which you know takes < 10ms then C is reasonably predictable (ignoring whatever variability your operating system might introduce).
Having said that for very tight long loops (image processing for example), things like C/C++ can offer some speed up. You can get quite reasonable performance out of C#, you do have to be careful how you program it though, but I have found in general, you can still squeeze more out of C/C++
Usually your preferred language will do whatever you need it to in acceptable time (er, blazing fast).
Sure, critical time/performance functions can be written in a "more optimal/suitable" language like C or assembly - but whether it will actually make things faster is another story. There are laws that govern how much actual/overall speed-up that you'll get, specifically Amdahs Law and (diminishing returns) .
To answer your question, it only makes sense to rewrite these critical functions in lower languages if there is good enough speed-up to warrant the extra work.
I suggest you read Cliff Click's excellent Java vs. C Performance....Again.. It outlines many points of comparison between Java and C++.
Predictably, the conclusion is that it depends, but it's a worthwhile read.
You can only really answer this on a case by case basis and without reference to what you are doing it's impossible to answer.
But maybe what you actually want here is some kind of sanity check to ensure that this approach isn't crazy to consider. I have worked on tools ranging from a very large graphics application (~ million lines) to relatively small physical simulation engines (~10000 lines) there were written just as you describe: Python on the outside for interface (both for API and for GUI), C/C++ on the inside for the heavy lifting. They all benefited from this division of responsibility.
This is done especially with scripting languages. Things that come to mind are games made in Python. Most of the time Python is too slow for some of the more number crunching aspects of games and they make this a C module for speed. Be sure that you actually need the speed though and that number crunching is your performance bottleneck and not a general algorithm issue. Doing a brute-force search over a list is going to be slow in both C and Python.
I'd say that it depends a lot on your application.
What sort of performance is important? short startup-time? high throughput? low latency? Is it important that response time is always predictable?
Is the application short lived or does it run for long periods of time?
Java can give you high throughput, but occasional short freezes while doing garbage collection. C# is probably similar.
Python, well the performance there will often lag behind the others for anything not written in C (some things ARE written in C, even if you didn't do it yourself).
So as others said. It depends.
But as always with performance: Measure first, optimize when you know you need to.

Resources