Coffeescript and C Macros: Clean and Fast

Anyone who programs in C uses pre-processor macros to keep the code clean, maintainable and sometimes to improve run-time performance. You can use the same C pre-processor to include macros in Coffeescript or Javascript code, and it is easy!

The coffeescript file needs to be renamed with .c extension before running it thrrough gcc; otherwise, it gives a warning and doesn’t run the pre-processor. There may be some option to force it compile without checking the extension.

cp [source.coffe] [source.c]
gcc -E [source.c] > [processed.coffee]

Examples #

Improve performance #

This is the code with macros. It compares the time taken to calculate the sum of squares, using functions and macros.

square = (x) -> x * x

#define SQUARE(x) (x * x)

total = 0
console.time "no macro"
for i in [0...100000]
 total += square i
console.timeEnd "no macro"
console.log "Total #{total}"

total = 0

console.time "macro"
for i in [0...100000]
 total += SQUARE(i)

console.timeEnd "macro"
console.log "Total #{total}"

Compiled code:

# 1 "macro.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "macro.c"
square = (x) -> x * x



total = 0
console.time "no macro"
for i in [0...100000]
 total += square i
console.timeEnd "no macro"
console.log "Total #{total}"

total = 0

console.time "macro"
for i in [0...100000]
 total += (i * i)

console.timeEnd "macro"
console.log "Total #{total}"

Output:

no macro: 2ms
Total 333328333350000
macro: 1ms
Total 333328333350000

Debugging #

You can use you favorite DEBUG macro to define LOGS, and even __LINE__ and __FILE__

#define DEBUG

#ifdef DEBUG
#define LOG(x) console.log __LINE__ + ": " + (x)
#else
#define LOG(x)
#endif

n = 3
LOG("Root of #{n} = #{Math.sqrt(n)}")

There is a slight problem because # is used for comments in Coffeescript. All you need to do is to use ## instead of a single # when you want to add a comment.

#define DEBUG

##This is a comment

#ifdef DEBUG
## Define LOG macro
## Print line number
#define LOG(x) console.log __LINE__ + ": " + (x)
#else
#define LOG(x)
#endif

n = 3
LOG("Root of #{n} = #{Math.sqrt(n)}")
 
29
Kudos
 
29
Kudos

Now read this

Bye bye jQuery Mobile

jQuery Mobile lets you create slick mobile web applications, and that’s what we did with nearby.lk. However, when we wanted to add more content and customize it heavily, jQuery Mobile stood in our way. So we decided to move away from it.... Continue →