[.NET][C#]当然っちゃ当然だけどDataTableとか使いようによっては遅い

[]

今日は、ちょっくら調べ物でした。
そこで、気づいたのがDataTableとかって便利だけど使い方によっては遅いぞと。

有名どころでは、型指定でないDataSetで、DataTableからDataRowを取得してカラムのデータにアクセスするときに文字列で列名指定すると遅めだよというのがあります。

ということで、DataRowのカラムのデータにアクセスするときに文字列でアクセスするパターンとDataColumnでアクセスするパターンとインデックスで指定するパターンを試してみました。

実験コード

using System; using System.Data; using System.Diagnostics; using System.Text; namespace DataTableSpeed { class Program { // 列数 private const int COLUMN_COUNT = 30; // 行数 private const int ROW_COUNT = 50000; static void Main(string[] args) { var dt = MakeDataTable(); AccessColumnName(dt); AccessDataColumn(dt); AccessIndex(dt); } // テスト用データテーブルを作成する private static DataTable MakeDataTable() { var dt = new DataTable(); // カラム作成 for (int i = 0; i < COLUMN_COUNT; i++) { dt.Columns.Add("COL_" + i, typeof(string)); } // 行データ追加 for (int i = 0; i < ROW_COUNT; i++) { var row = dt.NewRow(); foreach (DataColumn col in dt.Columns) { row[col] = col.ColumnName + "_" + i; } dt.Rows.Add(row); } return dt; } // 列名でアクセス private static void AccessColumnName(DataTable dt) { var watch = new Stopwatch(); watch.Start(); foreach (DataRow row in dt.Rows) { var sb = new StringBuilder(); foreach (DataColumn col in dt.Columns) { // 文字列でアクセス! sb.Append(row[col.ColumnName]); } } watch.Stop(); Console.WriteLine("列名でアクセス: " + watch.ElapsedMilliseconds + "ms"); } // 列名でアクセス private static void AccessDataColumn(DataTable dt) { var watch = new Stopwatch(); watch.Start(); foreach (DataRow row in dt.Rows) { var sb = new StringBuilder(); foreach (DataColumn col in dt.Columns) { // DataColumnでアクセス sb.Append(row[col]); } } watch.Stop(); Console.WriteLine("DataColumnでアクセス: " + watch.ElapsedMilliseconds + "ms"); } // インデックスでアクセス private static void AccessIndex(DataTable dt) { var watch = new Stopwatch(); watch.Start(); foreach (DataRow row in dt.Rows) { var sb = new StringBuilder(); for (int i = 0; i < COLUMN_COUNT; i++) { // インデックスでアクセス sb.Append(row[i]); } } watch.Stop(); Console.WriteLine("インデックスでアクセス: " + watch.ElapsedMilliseconds + "ms"); } } }

結果
image

DataColumnとインデックスでのアクセスはまぁいいとして、列名でアクセスするときは倍くらい時間がかかってそうに見えます。
因みに型付DataSetを使うと以下のようなコードでDataRowにプロパティが定義されます。

public string Col1 { get { try { return ((string)(this[this.tableDataTable1.Col1Column])); } catch (global::System.InvalidCastException e) { throw new global::System.Data.StrongTypingException(“テーブル ‘DataTable1’ にある列 ‘Col1’ の値は DBNull です。”, e); } } set { this[this.tableDataTable1.Col1Column] = value; } }

ここのthis.tableDataTable1.Col1ColumnはDataColumnなので、DataColumnを使ったアクセスをしてくれます。
性能的にも生産性的にも型付DataSetが使えるシーンでは使っておくほうが無難だと思われます。

次!!

これは知らなかった。
考えりゃ当然っちゃ当然な気もするけど、DataTable#Rows[index]へのアクセスも必要最低限にするようにすると早くなります。しかも件数が多いと結構効いてくる。

実験コード

using System; using System.Data; using System.Diagnostics; using System.Text; namespace DataTableSpeed { class Program { // 列数 private const int COLUMN_COUNT = 30; // 行数 private const int ROW_COUNT = 50000; static void Main(string[] args) { var dt = MakeDataTable(); SlowIndexAccess(dt); SmartIndexAccess(dt); ForEachAccess(dt); } // テスト用データテーブルを作成する private static DataTable MakeDataTable() { var dt = new DataTable(); // カラム作成 for (int i = 0; i < COLUMN_COUNT; i++) { dt.Columns.Add("COL_" + i, typeof(string)); } // 行データ追加 for (int i = 0; i < ROW_COUNT; i++) { var row = dt.NewRow(); foreach (DataColumn col in dt.Columns) { row[col] = col.ColumnName + "_" + i; } dt.Rows.Add(row); } return dt; } // 非効率な感じ private static void SlowIndexAccess(DataTable dt) { var watch = new Stopwatch(); watch.Start(); for (int row = 0; row < ROW_COUNT; row++) { var sb = new StringBuilder(); for (int col = 0; col < COLUMN_COUNT; col++) { // ループ内で毎回Rowsを使ってアクセス sb.Append(dt.Rows[row][col]); } } watch.Stop(); Console.WriteLine("ループ内で毎回Rowsを使ってアクセス: " + watch.ElapsedMilliseconds + "ms"); } // 効率的な感じ private static void SmartIndexAccess(DataTable dt) { var watch = new Stopwatch(); watch.Start(); for (int row = 0; row < ROW_COUNT; row++) { // 一度だけRowsにアクセスする var dataRow = dt.Rows[row]; var sb = new StringBuilder(); for (int col = 0; col < COLUMN_COUNT; col++) { // daraRow変数を使いまわす sb.Append(dataRow[col]); } } watch.Stop(); Console.WriteLine("必要最低限のRowsへのアクセス: " + watch.ElapsedMilliseconds + "ms"); } // まかせる private static void ForEachAccess(DataTable dt) { var watch = new Stopwatch(); watch.Start(); // foreachによるアクセス foreach (DataRow dataRow in dt.Rows) { var sb = new StringBuilder(); for (int col = 0; col < COLUMN_COUNT; col++) { // daraRow変数を使いまわす sb.Append(dataRow[col]); } } watch.Stop(); Console.WriteLine("foreachでアクセス: " + watch.ElapsedMilliseconds + "ms"); } } }

実行結果
image

これは当然。汎用的なメソッド程遅いのが道理。
どれくらい違うのか試してみました。

実験コード

using System; using System.Data; using System.Diagnostics; using System.Text; using System.Linq; using System.Collections.Generic; namespace DataTableSpeed { class Program { // 列数 private const int COLUMN_COUNT = 30; // 行数 private const int ROW_COUNT = 50000; static void Main(string[] args) { var dt = MakeDataTable(); UseSelect(dt); UseLinq(dt); UseLoop(dt); } // テスト用データテーブルを作成する private static DataTable MakeDataTable() { var dt = new DataTable(); // カラム作成 for (int i = 0; i < COLUMN_COUNT; i++) { dt.Columns.Add("COL_" + i, typeof(string)); } // 行データ追加 for (int i = 0; i < ROW_COUNT; i++) { var row = dt.NewRow(); foreach (DataColumn col in dt.Columns) { row[col] = col.ColumnName + "_" + i; } dt.Rows.Add(row); } return dt; } private static void UseSelect(DataTable dt) { var watch = new Stopwatch(); watch.Start(); // COL_1の値がCOL_1_10000の列が欲しいねん var ret = dt.Select("COL_1 = 'COL_1_10000'"); watch.Stop(); Console.WriteLine("Selectで検索: " + watch.ElapsedMilliseconds + "ms"); } private static void UseLinq(DataTable dt) { var watch = new Stopwatch(); watch.Start(); // COL_1の値がCOL_1_10000の列が欲しいねん var col1 = dt.Columns["COL_1"]; var ret = dt.AsEnumerable().Where(row => (string)row[col1] == “COL_1_10000”).ToArray(); watch.Stop(); Console.WriteLine(“Linqで検索: ” + watch.ElapsedMilliseconds + “ms”); } private static void UseLoop(DataTable dt) { var watch = new Stopwatch(); watch.Start(); // COL_1の値がCOL_1_10000の列が欲しいねん var col1 = dt.Columns[“COL_1”]; var list = new List(); foreach (DataRow row in dt.Rows) { if ((string)row[col1] == “COL_1_10000”) { list.Add(row); } } var ret = list.ToArray(); watch.Stop(); Console.WriteLine(“ループで検索: ” + watch.ElapsedMilliseconds + “ms”); } } }

実行結果
image

ということで、Selectがダントツで遅いです。
いっぱつ限りならいいですが、ループ内でSelectを使って検索を繰り返すときはLinqかループでごりっとやっちゃいましょう。

 

ということを今日体感しました。


Source pg slot, pgslot,pg slot auto,pg slot game,pgslot download,pg slot download ios,สล็อตพีจี,พีจีสล็อต,สล็อตออนไลน์,pgslot168,slot pg, บาคาร่า, แทงบอล, ผลบอล, การพนัน, พนันออนไลน์, ไพ่,poker, เกม, เกมส์, gambling, slot, baccarat, slot machine, how to win slot,joker123, joker123, joker123ทางเข้า, เครดิตฟรี,joker gaming, superslot, superslot168, pgslot168 สล็อตออนไลน์ คืออะไร ใครสงสัยมีคำตอบ คือ มี joker123 jokerwallet pgslot pg slot ในภาษาอังกฤษ แปลว่า เต็ม ทั้งหมด สมบูรณ์ space ก็คือ เกมคาสิโนออนไลน์ที่เรารู้จักกันเป็นอย่างดีนั้นคือ เกมพนันรูปแบบโปแกรมเพราะเป็นการเล่นด้วยระบบของคอมพิวเตอร์จากในอดีตเป็นตู้เกมแมชชีนแต่ในปัจจุบันเป็นเกมสล็อตออนไลน์ที่เล่นได้อย่างสะดวกผ่านหน้าเว็บไซต์ในปัจจุบันไม่ต้องดาวน์โหลดแล้วละคะ สามารถเล่นเกมได้ที่หน้าเว็บได้เลย แล้วอะไรที่เรียกว่าเป็นเกมส์สล็อตที่มีความครบครันละ นั้นก็คือ เว็บเกมที่เปิดให้บริการคาสิโนออนไลน์แบบครบวงจรไม่ต้องไปตามหาที่ไหน มีครบจบในเว็บเดียว ไม่ว่าจะเป็น แทงบอล บาคาร่า สล็อตออนไลน์ที่กำลังเป็นที่นิยมของนักลงทุนบอกเลยว่าว่าเว็บมีทั้งสามเกมนี้ให้เล่นเว็บนั้นคือเดอะเบอสของเว็บคาสิโนออนไลน์ชั้นนำปัจจุบัน opening on the web มีให้บริการอย่างแพร่หลาย บางเว็บก็จะแยกเฉพาะให้บริการบางเว็บก็จะรวบรวมสารพัดเกมเดิมพันไว้ในเว็บเดียวข้อดีของการใช้บริการเว็บที่ให้บริการเกมคาสิโนออนไลน์ครบวงจรนั้นก็คือ ไม่ต้องมีหลายยูสเซอร์ให้งงอย่างเช่นเราต้องการเล่นเกมส์ บาคาร่า แต่เว็บนี้ไม่มีก็ต้องไปสมัครเป็นสมาชิกกับเว็บอื่นให้เสียเวลาไปอีกแล้วอีกทั้งยังต้องเติมเงินเล่นที่อาจจะทำให้เสียเงินมากกว่าได้เงินด้วยซ้ำการที่เรามียูสเซอร์เดียวแล้วสามารถเล่นได้ทุกเกมที่ต้องการถือว่าเป็นสิ่งที่คุ้มค่ามากค่ะโดยที่เติมเงินรอบเดียวแต่หาเงินได้ถึงหลายเกมส์ ยิงปืนนัดดียวได้นกหลายตัวเลยละคะและเว็บเหล่านี้โดยส่วนมากจะเป็นเว็บที่ใหญ่ มีมาตรฐานสูง การทำงานบริการเป็นระบบ เชื่อถือได้ส่วนมากจะมีประสบการณ์ด้านการบริการเกมคาสิโนสูงมาก ความแม่นยำดีเยี่ยมทำให้การลงทุนของเรานั้นจะมีความปลอดภัยมากนั้นเองค่ะ แล้วการที่จะใช้บริการเกมก็ไม่ต้องสับสนไปค่ะ จะมีการแยกหน้าเว็บเข้าใช้บริการอย่างละเอียดเช่น เข้า Ufa ,เว็บ Ufabet, บาคาร่าฟรี ,เว็บ Royal, Ufaแบ่งให้ชัดเจนสามารถเข้าไปคลิ๊กเลยเล่นได้สบายเลยละคะ เป็นอย่างไรบางคะก็หวังว่าบทความนี้พอจะทำให้ทุกท่านเข้าใจความหมายของ fullslotและตัดสินใจสำหรับการลงทุนของท่านเองให้เหมาะสมกับความต้องการเพราะการที่จะมีเกมครบหรือไม่ครบของคาสิโนแต่ละเว็บนั้น ข้อดีข้อเสียก็จะขึ้นอยู่กับความต้องการของผู้ใช้บริการใครที่ต้องการเกมที่เป็นสล็อตโดยตรงก็สามารถเลือกเว็บที่มีความเชี่ยวชาญดูแลเกมสล็อตออนไลน์โดยตรงก็ได้แต่ใครที่ต้องการทุกอย่างในหนึ่งเดียวเพื่อเพิ่มรสชาติของการลงทุนให้มีความสนุกมากยิ่งขึ้นก็เลือกเว็บที่ตอบโจทย์ตรงสไตล์ของแต่ละท่านนะคะสุดท้านนี้ก็ข้อให้การลงทุนของคุณประสบความสำเร็จค่ะ

Leave a Comment

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *