はじめに
新卒から.netを触り始めて早4年。.net frameworkでVB.netからキャリアをスタートさせて、今はASP.NET Coreをメインに触れています(もちろんC#です)。
最初は、framework?なんじゃそれ??、プログラミング言語と何が違うん?
といったレベルで、開発環境そのものの理解も覚束ない、エンジニア(仮)みたいな知識レベルでした。
さすがに4年も触れていると、「ああ、frameworkってこのレベルまで違うのね」程度の感覚までは言語化することができるようになったので、ようやくバックエンドエンジニアとして一本毛が生え始めたくらいまでの理解力は得られました。
そんな折にして、転職してからNode.jsというものに触れ始めて、NPM?YARN?という新しい壁にぶち当たり、結局ここでも理解するのに苦労する始末。
しかし使ってみると、これまで.netしか使ってこなかったものも相まって、両バックエンドプラットフォームをぼんやりと比較することがありました。
そこでせっかくなら、両プラットフォームをきちんと調べて、両方の違いと利点を改めて言語化しようかなと思いここにまとめてみようと思います。
それぞれの特徴
以下の2点を比較しようと思います。
・基本的な開発言語
・基本アーキテクチャの違い
まず、基本的な違いを表形式でまとめてみましょう。
特徴 | .net(ASP.NET Core) | Node.js |
---|---|---|
実行エンジン | .NET ランタイム | V8 JavaScript エンジン |
対応言語 | C#、F#、VB.NET | JavaScript、TypeScript |
開発パッケージマネージャー | NuGet | npm、yarnなど |
ざっとこんなものですね。
基本アーキテクチャについて、詳しくみてみましょう。
V8 JavaScriptはGoogleが開発したJavaScriptエンジンです。
Google chromeのバックエンドでもこのJSが使われているそうです。
基本アーキテクチャの違い
・.net(ASP.NET Core)
・ マルチスレッドプールを採用
→.netランタイムが自動でスレッド(CPUが作業できる単位数)の増減を調整して、アプリ負荷がかからないよう効率的に処理を行っています。スレッドをひとまとめに処理を行うことを、マルチスレッドプールといいます。
・非同期処理
→スレッドを効率的に管理できる.netは、非同期処理とかなり相性が良いです。
たとえば、async/awaitを使用してI/O処理を行えば、限られたスレッドを占有せず多数のリクエストを並行して行うことができます。
・CLRによるバックグラウンド処理
→CLRとは簡単に言えば、プログラミング言語を機械語に翻訳する共通言語のことです。その名の通り、C#以外の言語でコンパイルされても、ランタイムしてくれます(クロスプラットフォームといいます)。
さらにCLRには「ガベージコレクション」 = スレッドプールを自動管理してくれる機能があり、自動で不要なメモリを解放してくれます。
・Node.js
・シングルスレッド
+ イベントループ
→一方で、Node.jsではシングルスレッドです。それだとめっちゃ遅くない?って思いますが、複数のことを並行して行えるように見せるイベントループというのを取り入れています。
・非同期処理
Node.jsも同じく、async/awaitによるスレッドがブロッキングされないようなI/O操作をしています。javascriptにもともとあるPromiseも併用しているようです。
・libuvライブラリによるバックグラウンド処理
シングルスレッドではありますが、I/O操作するときはスレッド プールを使っています。それがこの、C++で作られたlibuvです。マルチスレッド、ファイル、ネットワーク操作まで対応して、しかもクロスプラットフォームという優れものです。
終わりに
ざっと書き上げてしまいましたが、それぞれの特徴を踏まえて開発領域に適したユースケースは以下のようになるでしょうか。
.net(ASP.NET Core)
複数のスレッドを効率良く処理行い、不要なメモリを自動開放してリソースを最適化してくれる。
⇒ 計算負荷の高いシステム(金融などの大規模システム)に向いている
Node.js
軽量なシングルスレッドと非同期処理によるノンブロッキングなI/O操作が行える。
⇒ 即起動・停止ができるマイクロサービス(チャットアプリなど)に向いている
Node.jsのイベントループはかなり混乱して、乱筆になってしまったかもしれません(勉強不足...)。もう少し経験を積んで、イベントループ単体で記事をあげたいですね。