DEVTOME.COM HOSTING COSTS HAVE BEGUN TO EXCEED 115$ MONTHLY. THE ADMINISTRATION IS NO LONGER ABLE TO HANDLE THE COST WITHOUT ASSISTANCE DUE TO THE RISING COST. THIS HAS BEEN OCCURRING FOR ALMOST A YEAR, BUT WE HAVE BEEN HANDLING IT FROM OUR OWN POCKETS. HOWEVER, WITH LITERALLY NO DONATIONS FOR THE PAST 2+ YEARS IT HAS DEPLETED THE BUDGET IN SHORT ORDER WITH THE INCREASE IN ACTIVITY ON THE SITE IN THE PAST 6 MONTHS. OUR CPU USAGE HAS BECOME TOO HIGH TO REMAIN ON A REASONABLE COSTING PLAN THAT WE COULD MAINTAIN. IF YOU WOULD LIKE TO SUPPORT THE DEVTOME PROJECT AND KEEP THE SITE UP/ALIVE PLEASE DONATE (EVEN IF ITS A SATOSHI) TO OUR DEVCOIN 1M4PCuMXvpWX6LHPkBEf3LJ2z1boZv4EQa OR OUR BTC WALLET 16eqEcqfw4zHUh2znvMcmRzGVwCn7CJLxR TO ALLOW US TO AFFORD THE HOSTING.

THE DEVCOIN AND DEVTOME PROJECTS ARE BOTH VERY IMPORTANT TO THE COMMUNITY. PLEASE CONTRIBUTE TO ITS FURTHER SUCCESS FOR ANOTHER 5 OR MORE YEARS!

Playing with LuaJIT FFI

What is LuaJIT?

Lua was for long time one of the fastest programming languages, and perhaps sounds new to you but it appeared on 1993, it is actually older than PHP! Then, LuaJIT emerged on 2005, quickly earning the title of “The fastest Lua interpreter”, and I think it can make V8 look like a turtle!

What is FFI?

One of the greatest features I love of LuaJIT is its FFI, which can speed up even more the performance. Do you remember the DLL Calls? the idea is to make direct calls to functions inside libraries, because certainly there are heavy tasks that C can handle better, and there are plenty of libraries over there. Now you don't need to code bindings all the time, with LuaJIT you just load the library and it does the magic for you! Another advantage of FFI is the reuse of a wide variety of C libraries, being the most used programming languages, most of them are pretty mature and are spread over major platforms (some are cross-platform).

Example 1

Enough talk about how great is FFI, now it is time to code something. My first try was with libcurl, here is the original C code:

#include <stdio.h>
#include <curl/curl.h>
 
int main(void)
{
  CURL *curl;
  CURLcode res;
 
  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
    res = curl_easy_perform(curl);
 
    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return 0;
}

The previous example does a fetch of example.com and exists. Pretty easy.

Now let's do the same with LuaJIT's FFI:

local ffi = require [[ffi]]

ffi.cdef[[
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("libcurl.so.3")
local CURLOPT_URL = 10002

local curl = libcurl.curl_easy_init()

if curl then
  libcurl.curl_easy_setopt(curl, CURLOPT_URL, "http://example.com")
  res = libcurl.curl_easy_perform(curl)
  libcurl.curl_easy_cleanup(curl)
end

Drawbacks

There are some drawbacks, like the need of declaring the functions that are going to be used from the loaded C library. But 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 it would be to use C libraries directly instead of re-implementing in PHP code or writing plug-ins, perhaps my programs would have better performance and less code. In the other hand, 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. There are few uses cases that can benefit from FFI, but it does not means that has a lot of potential on the fields of performance tuning and code reuse.

Example 2

Let's give it another try. This time we are implementing 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.printf([[Hello]])

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

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

Output:

 World!

The code is pretty eloquent, a classic example of “Hello World!” is now used to split the text into an output buffer and the standard output.

Conclusion

LuJIT's FFI is an option one has to consider. There are some drawbacks like mentioned before, but there are solid points as well. Just make sure to remember that you will need to spend some time playing with FFI and getting familiar with the C library you are working with. Must confess that felt very frustrated at some point, when there were some “Segmentation fault” errors, memory leaks and other unexpected behaviors. If you are not used to code with C, then it is better to ask for support from an expert.

Programming


QR Code
QR Code playing_with_luajit_ffi (generated for current page)
 

Advertise with Anonymous Ads