概要
プログラミング言語は、PythonやJavaScriptに代表されるインタプリタ言語とCやC++に代表されるコンパイラ言語の2つに分類されます。インタプリタ言語は逐次解釈されながらプログラムが実行される言語であり、コンパイラ言語はコンパイラによりソースコードが機械語に変換され、それをCPUが実行する言語です。
この違いを実際に呼び出されるシステムコールの違いから見てみようというのが本記事の目的です。
straceコマンドについて
straceコマンドは、プログラムが発行するシステムコールと受信するシグナルを追跡するためのツールです。デバッグやパフォーマンスの分析に非常に有用です。以下は基本的な使い方です。
strace -o <出力ファイル名> <コマンド>
実験
本実験はUbuntu(WSL2)で動作させています。
Hello, World!と出力するプログラムをPythonとC++で用意します。
print("hello, world!")
#include<iostream>
using namespace std;
int main(void){
cout << "Hello world!" << endl;
return 0;
}
C++のプログラムはコンパイルし、<ファイル名>.oというファイルを生成しておきましょう。
g++ -o hello hello.cpp
それぞれ実行時間を測りながら実行してみましょう。
time python3 hello.py
time ./hello
Pythonでは0.030s、C++では0.014sでした。
インタプリタ言語のPythonより、コンパイラ言語のC++の方が実行が速い様子を確認できます。では実際に発行されているシステムコールに違いはあるのでしょうか?straceコマンドで確かめてみましょう。
strace -o python.log python3 hello.py
strace -o cpp.log ./hello
これらを実行するとpython.logとcpp.logという2つのファイルが出来ています。このファイルにプログラムが実行される際に発行されたシステムコールが記載されています。行数だけ見ると、自分の環境ではpythonが500個のシステムコール、C++が70個のシステムコールを呼び出していました。
単純にシステムコールを呼び出す回数がインタプリタ言語であるpythonだと多いですね!ここからも実行速度がコンパイラ言語の方が速いというのが直感的に分かります。
具体的なシステムコールを見てみると、C++ではwriteシステムコールが呼び出されているのに対し、Pythonではreadシステムコールでプログラムが読み込まれたのちにwriteシステムコールで書き出している様子が分かります。
read(3, "print(\"hello, world!\")", 512) = 22
...
write(1, "hello, world!\n", 14) = 14
write(1, "Hello world!\n", 12) = 12
まとめ
今回の実験では、インタプリタ言語であるPythonとコンパイラ言語であるC++の違いをシステムコールの違いから眺めてみました。結果として、C++の方が実行速度は速く、システムコールの呼び出し回数も少ないことが確認できました。たった数行のプログラムですが、たくさんのシステムコールが裏側では呼び出されていることも実感できます。