AWS Lambda currently supports Lambdas written in Java, Node.js, C#, and Python code with more language support coming in the future.
I was thinking about how to run a very fast native function, e.g. compiled with Rust with no dynamically linked libs (all static) and found an article showing how to launch the executable even though it is not yet directly supported by AWS by wrapping it in a node.js lambda.
This got me thinking, is node the fastest way to do this, after all if I’m a speed freak and writing Rust then launch times are important to me…
So I looked at at launching a process from node and python and timing it, I did not investigate C# or Java as they will always take longer to start because their runtime is doing more stuff.
This is not a statistically viable experiment (I only ran it once :-) but I built a shell tool called launch.sh, see the gist, to spit out a date including nanoseconds (my laptop supports this) then kick of a python app that uses a subprocess to run the same date command twice from within the python app. It then does the same using node.js.
Running it I get this data :-
me@storm:~/bin$ ./launch.sh start launch python data subprocess... 09:57:25 1489532245 519378382 09:57:25 1489532245 530775400 09:57:25 1489532245 531650629 start launch python compiled data subprocess... 09:57:25 1489532245 533984993 09:57:25 1489532245 541690675 09:57:25 1489532245 542552837 Now using node v7.6.0 (npm v4.1.2) start launch node subprocess 09:57:25 1489532245 712281203 09:57:25 1489532245 750742945 09:57:25 1489532245 751821095
The first date in each triplet is the date at the shell before launching python or node followed by the subprocess date commands inside the python or node script.
The last set of numbers on each line is nanoseconds.
I also pre-compiled a python script to see if it was faster than executing the script, but forgot that python would do a search for pre-compiled scripts version of commands so the results of the first two are probably actually running the compiled version, the first is slower to launch presumably searching to see if there is a pre-compiled version in the directory (N.B. this is a guess as I don’t have enough data here to prove it). Regardless I removed the compiled python and ran again to get un-compiled time data:
start launch python data subprocess... 10:34:30 1489534470 041312697 10:34:30 1489534470 054794071 10:34:30 1489534470 055933101
The results are :-
Uncompiled python takes 13481374 ns to launch and run the subprocess Uncompiled python takes 1139030 ns to launch and run a subprocess once it is already running Compiled python takes 7705682 ns to launch and run the subprocess Compiled python takes 862162 ns to launch and run a subprocess once it is already running node.js takes 38461742 ns to launch and run the subprocess node.js takes 1078150 ns to launch and run a subprocess once it is already running
So the results show it is currently best to use compiled python to kick off a sub process e.g. a Rust or Go procedure in AWS lambda
When Go or Rust are natively supported by AWS Lambda containers no doubt the story will change.