Lua was for long time one of the fastest programming languages, and perhaps sounds new to you but it is older than PHP. LuaJIT has emerged as an improved implementation that can make V8 look like a turtle.

One of the greatest features I love of LuaJIT is its FFI, which can speed up even more the performance, because certainly there are heavy tasks that C can handle better, and there are plenty of libraries over there, but you don't need to code bindings all the time, with LuaJIT you just load the library and it does the magic for you!

My first try was with libcurl, here is the original C code:


int main(void)
  CURL *curl;
  CURLcode res;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "");
    res = curl_easy_perform(curl);

    /* always cleanup */
  return 0;

And the corresponding code ported to LuaJIT:

local ffi = require [[ffi]]

void *curl_easy_init();
int curl_easy_setopt(void *curl, char option, ...);
int curl_easy_perform(void *curl);
void curl_easy_cleanup(void *curl);
local libcurl = ffi.load([[]])
local CURLOPT_URL = 10002

local curl = libcurl.curl_easy_init()

if curl then
  libcurl.curl_easy_setopt(curl, CURLOPT_URL, [[]])
  res = libcurl.curl_easy_perform(curl)

NOTE: [[ is the Lua equivalent to " in C code.

The only drawback I care about is doing callbacks from C to Lua functions. By now possible but impractical, hopefully it is in the TODO list of the author.

NOTE: I do PHP code most of my day, but I'm seriously thinking on how great would be to use C libraries directly instead of re-implenting in PHP code or writing plug-ins, perhaps my programs would have better performance and less code. But Lua is not as mature as PHP for the web, so there is a long way till we see serious stuff that can compete with PHP.

A final example, output buffering using standard C functions:

local ffi = require [[ffi]]

ffi.cdef [[
typedef struct __IO_FILE FILE;
FILE *stdout;
int printf(const char *fmt, ...);
void setbuf(FILE *stream, char *buf);
void *malloc(size_t size);
void *memset(void *s, int c, size_t n);

local buffer = ffi.C.malloc(1024)

ffi.C.setbuf(ffi.C.stdout, buffer)

ffi.C.memset(buffer, 0, 1024)

local buffer = ffi.C.malloc(1024)
ffi.C.setbuf(ffi.C.stdout, buffer)
ffi.C.printf([[ World!




Cross-posted to Devtome