Karl's Code

and other code related stuff

AWS Lambda Launch Times - Is Python Faster Than Node.js ?

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.