関数内のnumpy.empty(...)の部分は計算とは関係ありませんがe-5秒くらいのオーダーだったので無視してよさそうです。(ちなみにですがnumpy.random.rand(...)の部分は無視できないほど時間がかかります。start_t)JITを有効化してみる以下のようにデコレータをつけて、JITを有効化してみます。ret測定の結果、出力は1.805896282196045となり、100倍ほどの高速化に成功しました。JITを有効化/並列化してみる以下のようにデコレータを変更し、range関数をnumba.prange関数に置き換え、並列化してみます。1)の部分は、numbaが勝手にうまいこと(hoist)してくれて、期待通りの動作をします。ret測定の結果、出力は0.7335679531097412となり、200倍以上の高速化に成功したことになります。まとめ限られたケースにはなりますが、Numbaをうまく使えば非常に簡単に高速化ができることがわかりました。typescript最近、バックエンド開発でNode.jsを用いています。JavaScriptは仕様がどんどん良くなってきているし、コールバックを用いた非同期処理も個人的には好きです。コードベースが大きくなると「型があればなあ...」と思うこともしばしば。そこでTypeScriptに足を突っ込んでみることにしました。Node.js/ExpressでWebバックエンドの開発を始める方法を紹介します。TypeScriptの文法・言語の機能についてはあまり触れません。(それらについては以下が参考になります。用いるなどして、package.jsonを作成します。--save-devJavaScriptからTypeScriptへのコンパイルに必要です。以下のような内容をtsconfig.jsonという名前で保存します。]}軽く説明すると、このようになります。「どの仕様に対応したJavaScriptのコードをコンパイルによって生成するか」を指定しています。ここではES5を指定しています。コンパイル後のコードを保存するディレクトリを指定します。trueにすることで、いろいろなTypeScriptのチェック機構が有効になります。コンパイルの対象にしたいファイル群を指定します。--save-devこのようにパッケージと一緒に型定義ファイルもインストールすることで、そのパッケージの関数やオブジェクトを使うときにもTypeScriptの型チェックを利用できるようになります。コマンドでTypeScriptコードを実行できるようになります。ts-nodeは、「tscを用いてTypeScriptのコードをJavaScriptへコンパイルし、それをnodeで実行する」ということをしてくれています。開発中に使うと便利です。本番環境での仕様は推奨されていません。中身を以下のように書き換えます。そのJavaScriptコードを実行できるようになります。その2つを組み合わせたことをやってくれますが、開発中のみ利用します。以下のコマンドでサーバーが起動します。dev以下のように、きちんと動いていることがわかります。用いて、エンドポイント単位のテストをしてみます。準備supertestのインストールsupertestは、Node.jsのHTTPサーバーをテストするためのライブラリです。型定義ファイルも同時にインストールします。https://github.com/visionmedia/supertestmochaのインストールmochaは、テストのためのフレームワークです。いう関数はmochaが提供しているものです。型定義ファイルも同時にインストールします。テストを実行できるようになります。より、JavaScriptによってコンパイルすること無くテストを実行できます。コードtest/routes.tsとても簡単なものです。(37ms)テストが通りました。ビルド・実行する本番環境で実行する際には、JavaScriptにコンパイル(ビルド)して、その結果生成されたファイルをNodeで実行する必要があります。このための準備はすでにできていて、以下のスクリプトを実行するだけで大丈夫です。特徴まとめawsAWSを使っている人全員が触ったことがあるであろうS3。ついてのメモaws使う機会がったので。ついてのメモaws使う機会があったので。読み進めていった際のメモです。概要libuvは「クロスプラットフォームサポートのためのライブラリ」で、Node.jsで使われることを想定して開発が進められてきた(現在はNode.js以外でも用いられている)。「イベント・ドリブンな非同期I/Oモデル」をもとに設計されていて、以下のようなものを提供しているプラットフォーム間で異なるI/Oポーリングの仕組みの抽象化(ハンドルとストリームによる)ソケットなどの抽象化ファイルI/Oやスレッド周辺の各種機能ハンドルとリクエストlibuvでは、イベントループとともに、ハンドルとリクエストという2つの抽象化された概念が用意されている。ハンドルは「(アクティブなときに)何らかの操作を行うことができる、長期的に存在するオブジェクト」を表す。その例としては以下のようなものがある。イベントループが一周するたびに一度呼ばれるprepareハンドル新しいコネクションができるたびにコールバックを実行するTCPサーバーハンドルリクエストは(一般的に)「短い期間で終わる有効な操作」を表す。リクエストはハンドルを通して行う(例:writeリクエストはハンドルを通してデータを書き込む)ことも、スタンドアロンで行う(例:getaddrinfoリクエストはハンドルを用いず、ループの中で直接実行される)こともできる。(イベントループ)I/Oループ(イベントループ)は、libuvの中核をなしている。イベントループはすべてのI/O操作を管理し、「一つのイベントループが一つのスレッドに対応する」ことが想定されている。異なるスレッドで動作する限り、複数のイベントループを利用することができる。ちなみに、イベントループ(そして、ループやハンドルに関係する他のAPI)は、基本的にはスレッドセーフではない。イベントループは、I/Oに対してシングルスレッドの同期的な(一般的な)アプローチを用いている。WindowsではIOCP)。ハングアップ)とともにコールバックが呼ばれる、これを用いてハンドルはI/O操作を行える。イベントループへの理解を深めるために、一回のループでどのようなことが行われているのかを確認する。「現在時刻」が更新される。イベントループは、ループの最初に取得した時刻をキャッシュすることで、時刻関係のシステムコールの発行回数を減らしている。ループが生きているのなら、イベントループの周回がはじまる。生きていないのなら、イベントループは終了する。(有効かつ参照されているハンドル、有効なリクエスト、またはclosingハンドルが存在する場合、イベントループは生きているとみなされる。)適切なタイマーが実行される。イベントループの「現在時刻」よりも前に設定されていたコールバックが呼ばれる。pendingコールバックが呼ばれる。多くのI/Oコールバックは、I/Oのポーリングの直後に呼ばれることが多い。コールバックの実行を(イベントループの)次の周回に遅らせるということもある。そのようにして前の周回で後回しにされたI/Oコールバックが、ここで実行される。idleコールバックが呼ばれる。prepareハンドルのコールバックが呼ばれる。これはイベントループがI/Oブロックをする直前に呼ばれる。pollタイムアウト(どれほどの時間I/Oのブロックを行うか)を計算する。計算は以下の通り行われる。一つ前のステップで計算した時間分だけ、I/Oのブロックをする。(読み書きのために)ファイルディスクリプタを監視しているI/O関連のハンドルはここで適当なコールバックを呼ぶ。checkハンドルコールバックが呼ばれる。checkハンドルのコールバックはI/Oのブロックの後に呼ばれ、prepareハンドルのコールバックと対を成している。closeコールバックが呼ばれる。よってcloseされた場合、そのハンドルはcloseコールバックを呼び出す。モードでループが走っている場合には、ループが生きてれば次の周回に入り、そうでなければループは終了する。libuvはファイルI/Oにおいてスレッドプールを用いているが、ネットワークI/Oは常にシングルスレッド(イベントループのスレッド)上で行う。pollingの機構はUnixとWindowsで大きく違うが、libuvは実行モデルに一貫性をもたせている。ファイルI/OネットワークI/Oとは違い、(設計上の困難さから)ファイルI/Oはスレッドプールを用いてファイルのI/Oを行っている。libuvは現在グローバルな(全てのイベントループが用いることのできる)スレッドプールを用意している。3種類の操作がこのプールで行われる。JavaScriptエンジンとは(そしてその高速化について少し)v8V8のロゴV8とはV8はGoogleが開発しているオープンソースのJavaScript実行エンジン(JavaScriptのコードを解析し、機械語まで落とし込んで実行してくれるもの)です。Chromeで使われているほか、Node.js(サーバーサイド向けのJavaScript実行環境)などにも組み込まれています。競合?として、MicrosoftのChakraやMozillaのSpiderMonkeyなどがありますが、全体的にパフォーマンスはV8に分があります。JavaScriptエンジンのパフォーマンスについてJavaScriptの実行エンジンで最も重要なのは「いかに高速にJavaScriptを実行できるか」です。「どれだけ広いJavaScriptの仕様に対応できるか」や「デバッグ機能の豊富さ」も忘れてはならない点ではあるものの、やはり一番差が出るのはパフォーマンスで、そして実行エンジンのパフォーマンスの差はブラウザのパフォーマンスに大きく影響します。そのために、ブラウザ(熾烈なシェア争いを繰り広げている)の開発元は実行エンジンのパフォーマンスの向上に努めてきました。そのおかげか、JavaScriptは動的型付けの言語にもかかわらず、実行エンジンのおかげでかなりのハイパフォーマンスで実行することができるようになっています。(似たようなCPUインテンシブな処理をPythonとJavaSriptで書いてみて比較したらJavaScriptのほうが早いことが多い。)V8の高速化についてそこで実際、V8がどのようにしてJavaScriptの実行を高速化をしているのか(一例だけど)を軽くまとめてみます。JavaScriptのコードがパースされ、抽象構文木が作られる。Ignitionというインタープリタが、その抽象構文木を元に、実行を始める(最適化するよりも、とにかく早く実行を開始するという雰囲気)Ignitionでの実行中に、ホットな関数(多く呼び出される関数)を特定し、さらにその関数がどういった種類(文字列なのか、数値なのか)の引数とともに呼び出されているのか、というデータを収集するそのデータをもとに、TurboFanがホットな関数をコンパイルし、最適な機械語を生成するその機械語を用いた実行を始めるもしも異なったタイプの引数が来てしまった場合(最適化した機械語を用いられない場合)は最適化前の処理に戻るこういった感じでV8はJavaScriptを実行するらしいです。特定の関数の引数には常に同じ型のものを渡してあげると、実行エンジンに優しいコードになるということですね。(1)リンクホームページfeedレビューのまとめスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。