Rustプログラミング言語の学習開始
はじめに
プログラミングが以前よりも重要なスキルだと世間に認識され,日本では義務教育でも導入する動きが広がっています.20年ぐらい前はプログラミングは限られた技術系の学校でしか教えていなかったと思います.私は高専出身ですが,初めて体系的にプログラミング言語に触れたのは一年生の授業での実習の時で,C言語を習いました.それまでは父親のPC9801のマニュアルに記載されていたポーカーゲームをBasicで入力して遊んでいた程度の知識で,C言語に触れたのがきっかけでシステムプログラミングを学びました.高専在学中にはロボットコンテストやプログラミングコンテストに参加しそのプロジェクトの中でアセンブラでの組み込み開発からC/C++による競技プログラミングを経験していきました.大学に編入学してからも画像処理を頻繁に行う研究室だったので,C/C++の本格的なGUIアプリ,科学技術シュミレーションやPerlやJava Scriptをつかったwebアプリやサイト構築などを経験しました.
最近では,30代後半でMATLABで書かれたコードが可読性が悪いのに高いライセンス料を取られていたことからコスト削減しようという軽いのりでPython学習も始め,今ではそれなりの規模のアプリケーションを構築できるまでマスターしてきました.
Pythonに触れてから現代的な思想で設計された新しいプログラミング言語の存在に注目するようになり,ブロックチェーンプロジェクトで頻繁に見かけるようになったRustにも興味が出てきました.
さて,ここでは自分がこれからRustを学んでいく上でのステップとしてRustの特徴と利点などを解説していこうと思います.
Rustの特徴
正式にリリースされたのは2015年と割と最近で,もともとMozilla Research社にいたGraydon Hoarce氏やJava Scriptの作者であるBrendan Eich氏が中心になって設計した言語でした.Rust言語は近年注目を集めており,海外サイト”Stack Overflow”で毎年開発者向けに行われる調査であるDeveloper Surveyで,“もっとも愛されている言語”部門のトップに2016年から5年連続で輝いています.最近ではMicrosoftやAmazonが正式に採用を決めていますしそれらからも注目度の高さが伺えます.
ではRustという言語はどんな特徴があるのでしょうか?
特徴をまとめると以下のようになります.
· 実行速度はC/C++並に高速
· モダン文法がサポートされている
· OSからWebアプリまで幅広く実装可能
· 安全性が強力に担保されている
ではそれらRustの特徴の一つ一つについて紹介していきます.
実行速度が高速
Rustはプログラムの実行速度重視で設計された言語です.プログラミング言語間の実行速度を比較するサイトでは,C/C++に匹敵する速度を達成することが可能なことが示されています.
処理内容によってはC言語を超える速度も達成します.ではなぜRustはPythonやJavaよりも高速実行が可能なのでしょうか.次のような要因が挙げられます.
· Rustは機械語に直接コンパイルされる
· ガベージコレクションを持たない
· “ゼロコスト抽象化‘を追求した言語設計
インタプリタ言語であるJavaやPythonは基本的に独自の仮想マシンを持ちバイトコードなどの中間言語に変換されたプログラムが実行されます.仮想マシンを入れるメリットは様々な環境下でプログラミング言語を実行しやすくなる点にあります.例えば,PythonはWindowsでもLinuxやMacOSXでも簡単に開発環境を構築できほぼ同じコードがそのまま動作します.さらに言えばJupiter Notebookとサーバーを使えばブラウザ上でも動作させることが可能です.
JavaやPythonはインタプリタやコンパイラを介して仮想マシン用のバイトコード(中間言語)を生成します.仮想マシンはソフトウェアで実装されているためにハードウェアの性能をフルに発揮することが難しく実行速度面では不利になります.
C/C++, Rustといった言語は,コンパイル後の最終結果は機械語になります.こうすると仮想マシンを介さずに実行できるので,仮想マシンに起因する速度低下は原理上発生しません.また,様々な環境下で実行できるように,GNU Compiler Collection (GCC)やLLVMといったコンパイラが,環境に応じた機械語を生成するような仕組みになっています.RustではLLVMが採用されています.
ガベージコレクションをもたない
RustはC/C++と同様に機械語にコンパイルされて実行されるために高速なのはわかりました.では,同様にコンパイルされるタイプのGoよりも高速なのはなぜでしょうか?これはガベージコレクションを持たないためです.
ガベージコレクション:
プログラムは普段ヒープメモリと呼ばれる領域を動的に確保したり開放したりしています.プログラムが処理中に確保したヒープメモリ領域のうち使う予定のなくなった不要なメモリ領域というものが必然的に生じます.この不要な領域をいつまでも開放しないと長時間処理していくうちにプログラムが使える領域がどんどん減っていってしまいます.そのため,ガベージコレクションという処理を挟むことで,そうした不要なメモリ領域を開放し,使えるヒープメモリ領域を増やすという処理をバックグラウンドで逐一行っています.
ガベージコレクションはプログラマーがメモリの動的確保や開放を意識せずにプログラミング可能なので便利な機能なのですが,問題もあります.不要なヒープメモリ領域がいつ開放されるのか分からないということと,不要なメモリ領域を開放する処理に時には数ミリ秒から数秒間にわたり本体の計算処理が止まってしまうことがあることです.大量にメモリを消費するアプリ作成などではこの停止時間というのは無視できるレベルではありません.GoとRustの速度差はこの点から生じていると言えるでしょう.
ここで疑問が湧いてきます.ガベージコレクションを持たない言語はどのように不要なメモリを開放しているのでしょうか?
例えば古い設計の言語であるC/C++はガベージコレクションを持ちません.これらの言語ではコードで明示的にメモリの確保と開放処理を記述します.ガベージコレクションのようにいつ不要になったメモリ領域が開放されるかわからないという不確定性の問題も開放時に計算処理を止めてしまう問題もありません.
しかし,これではプログラマーが手動でメモリ管理を行っていることになるので,それを意識してコードを書くことが要求されます.冗談ではなくメモリ開放を忘れたために永遠にメモリ確保を続けてPCをハングアップするようなプログラムが出来上がったりします(初心者がよくやるバグですw).もっと問題なのは開放した領域をもう一度開放しようとしたりします.こういった状況は専門用語で“メモリ安全でない”と言ったりします.
さて,Rustはどうでしょうか?Rustの場合は第3の方法を採用しました.プログラミング言語側がメモリ管理をおこないますが,“所有権”,“借用”,“ライフタイム”という新しい仕組みで実現しました.
プログラマがメモリ管理を直接行う必要はない一方で,ガベージコレクタにメモリ管理を任せる必要もないのです.メモリ安全で,かつ処理速度も低下させないプログラミング言語だといえます.
ゼロコスト抽象化の追求
このゼロコスト抽象化という概念もまた,Rustの高速実行を支えるキーの部分です.
ゼロコスト抽象化はもともとはC++で追求されていた概念になります.ゼロコスト抽象化とは,プログラミングが持つ抽象化の機能を追加コストを支払うことなく使用できることです.コストというのは,例えば実行速度やメモリの使用量のことを指します(ゼロコストの意味はそれらを犠牲にする必要がないことを意味します).
プログラムを抽象化するというのは,共通化が一番最適な例でしょう.似た処理やデータをまとめて大まかな動きを抽象化して記述すればあとは言語側がコンパイル処理時に展開しプログラムとして動作させることです.Rustではこの抽象化をゼロコストで行うことができるので動作速度の速さを達成できるのです.
まとめ
まずはRustの大まかな枠組みと基本設計概念を紹介しました.なんだか始める前から面白そうな雰囲気を醸しだしているプログラミング言語です.個人的にはGoを触ってしっくりこなかった経験から次世代のシステムプログラミング言語を探しているところでRustに出会いました.まだ規模が大きいアプリケーションソフトの開発はC++を使っており将来的にそれらの一部をRustに移植できたらいいなと考えています.
また,これから自分が学んだRustの使用方法などをこちらのNoteで不定期に紹介していこうと思っています.特に注目している点は,Rustを理解すると新しいブロックチェーンプロジェクトのソースコードがある程度読めることです.PolkadotやSolanaなどの新世代のブロックチェーンプロジェクトは必ずRustを使用しています.将来的にはスマートコントラクトも読めるようになることを目標にしていますが,そちらは追々暇を見つけて勉強していこうと思っています.
この記事が気に入ったらサポートをしてみませんか?