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 function
s 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)}")