(パラレル)データベースの例
上記のリストから分かるように、.NET Framework v2.0以降のフレームワーク全体にF#からアクセスすることができます。今度は、SQL Serverデータベースのデータを読み取る単純なデータベースアプリケーションを作成することを考えてみましょう。既にお分かりでしょうが、通常、これを実現するにはADO.NETを使用するのが最適です。そこで、System.Data.SqlClient名前空間のconnection
、command
、reader
などのクラスを使うことになります。
昔からあるおなじみのNorthwindデータベースからデータを読み取るコード例を次に示します。
let connStr = "Data Source=.;Initial Catalog=Northwind;\ Integrated Security=True;" let conn = new System.Data.SqlClient.SqlConnection(connStr) let sql = "SELECT [employeeid], [firstname], [lastname]\ FROM [employees]" let cmd = new System.Data.SqlClient.SqlCommand(sql, conn) conn.Open() let reader = cmd.ExecuteReader() reader.Read() printfn "Name = %s %s" (reader.GetString(1)) (reader.GetString(2)) reader.Close() cmd.Dispose() conn.Dispose()
この場合も、F#ではADO.NETを使って極めて直接的な方法でデータにアクセスできます。お分かりのように、C#コードをF#コードに変換するのは簡単です。作成する必要があるクラスとメソッドの呼び出しが変わらないためです。
多少の計算を追加すると、いろいろと面白くなってきます。例えば、消費税込みの製品の価格を計算する必要があるものとします。データベースからデータを取得するには、例えば、LINQクエリを使って2つの値配列を取得できます。1つは価格の配列で、もう1つは対応する価格の税率の配列です。
let prices = [100.0; 200.0; 50.0] let taxPercents = [5.0; 4.0; 7.0]
この2つの配列を使用すると、正しい価格を計算するcalculateTax
という関数を簡単に定義できます。その後、この2つのリストに対してList.map2
を実行します(map2
は、パラメータを1つではなく2つ受け取る場合のメソッドです)。
let calculateTax price tax = price * (1.0 + (tax/100.0)) let results = List.map2 calculateTax prices taxPercents printfn "results = %A" results
上のコードを実行すると、results
という新しい配列が返され、その値は[105.0; 208.0; 53.5]になります。もちろんこのコードで何も問題はないのですが、この計算を複数のスレッドで行い、最新のマルチコアプロセッサを活用したいならば、必ずしも十分ではありません。F#では、これを実に簡単に実現できます。
F#は組み込みの並列処理をサポートしており、async
キーワードが用意されています。税金を並列処理で計算する場合は、非同期コンテキストにList.map2
メソッド呼び出しを埋め込みます。
let results = Async.Run (Async.Parallel [ async { return List.map2 calculateTax prices taxPercents } ])
必要なのはこれだけです。配列の要素が3つしかない場合は、スレッドのオーバーヘッドがあるため、並列処理で税金を計算すると実際にはかえって時間がかかってしまいます。しかし、製品の個数が300,000の場合は、違いが明らかになってきます。