StringBuilderとStopwatch機能を使ってみた
StringBuilderはえー。 ミリ秒表示を調べるのに手こずった。 桁数揃えるのは切り捨て処理とか必要なのかな。ちょっと面倒。
class Program { static void Main(string[] args) { string Str = ""; DateTime StartDt = DateTime.Now; for(int i = 0; i< 30000; i++) { Str = Str + "ABCDEFG"; } DateTime EndDt = DateTime.Now; Console.WriteLine("String連結3万回:{0}秒",(EndDt - StartDt).TotalSeconds); StringBuilder stb = new StringBuilder(); Stopwatch Sw = new Stopwatch(); Sw.Start(); for (int i = 0; i < 300000; i++) { stb.Append("ABCDEFG"); } Sw.Stop(); double Sec = (double)Sw.ElapsedTicks / (double)Stopwatch.Frequency; Console.WriteLine("StringBulider30万回:{0}秒", Sec); // 実行結果 // String連結3万回:1.4610836秒 // StringBulider30万回:0.00474824136650194秒 } }
記事を公開したらタイマ計測方法は揃えた方がよいよとご指摘頂いた。あざます。きさとさん。
@fmty んー、時間の計り方はひとつの方法に揃えた方がいいかなと。メイン処理(string/StringBuilder)以外に実装差があると、そこでも時間差が出ているかもーと思われるので。
— きさと (@rkisato) 2015, 11月 20
ということで書き直してみた。回数も揃えた。
static void Main(string[] args) { string Str = ""; Stopwatch Sw = new Stopwatch(); Sw.Start(); for (int i = 0; i < 30000; i++) { Str = Str + "ABCDEFG"; } Sw.Stop(); double Sec1 = (double)Sw.ElapsedTicks / (double)Stopwatch.Frequency; Console.WriteLine("String連結3万回 :{0}秒", Sec1); StringBuilder stb = new StringBuilder(); Sw.Reset(); Sw.Start(); for (int i = 0; i < 30000; i++) { stb.Append("ABCDEFG"); } Sw.Stop(); double Sec2 = (double)Sw.ElapsedTicks / (double)Stopwatch.Frequency; Console.WriteLine("StringBulider3万回:{0}秒", Sec2); // 実行結果 // String連結3万回 :1.57325590253888秒 // StringBulider3万回:0.000421969408994146秒 }
DBの型を変更したらforeachでエラーがでるようになった
テーブルのとあるフィールドの型をintからfloatに変更したらforeachでエラーがでるようになった
using (DataContext db = new DBDataContext()) { // ストアドプロシージャ実行して値を取得 var n = db.GetData("2015-09-15"); foreach (var j in n) { Debug.WriteLine(j.id); } }
foreachの値変換で型が違うと怒られる。
色々アドバイスを頂きながら調べてみたところ、どうやらストアドプロシージャ名+Resultという型(今回だとGetDataResult)という型が自動実装されているらしく、そこの型が変わっていなかった模様。
手動でintからdoubleに変更したら問題なく動いた。
LINQ TO SQLクラス、DB側を変更した場合にどうやって同期させたらいいかがよくわかってない。これも要調査。
@fmty あ、ストアドの実行結果そのままじゃあかんはず。配列になっているのが間違いないならOfType(型)とかでその型のシーケンスに変換してやらないと。確かIDataRecordとかだったよーな
— ぽんこつロボ (@scrapbuild) 2015, 9月 15
イテレータ
クラス内において反復処理の機能を実装するためのforeachステートメントは、とかくプログラムコードが複雑に、かつ冗長になってしまうことがあります。 このような場合はイテレーターを利用することで反復処理のコードをシンプルにすることができます
参考書の説明を読んでも???だったけど、実際にコード書いてみたらなんとなくわかったような気がする。
下のコードの例のように、反復中に条件を挟みたい場合なんかはメインプログラム側で制御が必要になってくるけど、イテレータを使えば反復処理を外に出すことができるからメインプログラムをシンプルにできるってことかな。 うまく言語化できてないけど、こんな感じかな。
class Program { public static IEnumerable MethodShow(int days) { DateTime dt = DateTime.Today; for (int i = 1; i <= days; ) { if (dt.DayOfWeek != DayOfWeek.Monday && dt.DayOfWeek != DayOfWeek.Thursday) { yield return dt; i++; } dt = dt.AddDays(1); } } static void Main(string[] args) { foreach(DateTime dt in MethodShow(5)) { Console.WriteLine(dt.ToString("yyyy年MM月dd日(ddd)")); } } }続きを読む
型パラメータを持つクラスを実装してみる
ジェネリッククラスやディクショナリークラスの型パラメータ
今回の例だと普通にジェネリック使えばよさそうだけど、インデクサ(setやget)が実装できるので、この辺りに処理が挟めむケースとかなら便利かもしれない。
class Program { public class ListTest<T> { T[] list = new T[100]; int add; public void AddItem(T item) { list[add++] = item; } public T this[int Index] { get { return list[Index]; } set { list[Index] = value; } } } static void Main(string[] args) { // string型の配列を作成 ListTest<string> list = new ListTest<string>(); list.AddItem("hogehoge"); list.AddItem("fugafuga"); Console.WriteLine(list[0]); Console.WriteLine(list[1]); // DataTime型の配列を作成 ListTest<DateTime> list2 = new ListTest<DateTime>(); list2.AddItem(DateTime.Today); Console.WriteLine(list2[0]); // 普通にジェネリッククラスで作ってみる List<DateTime> list3 = new List<DateTime>(); list3.Add(DateTime.Today); Console.WriteLine(list3[0]); } }続きを読む
C# の配列の基本を復習。配列、リストアレイ、ジェネリック、ディクショナリ
コレクションについて復習をかねて色々調べてみた
まずは普通の配列
static void Main(string[] args) { int[] ArryTest = new int[5]; for(int i = 0;i < 5; i++) { ArryTest[i] = i + 100; } for (int i = 0; i < 5; i++) { Console.WriteLine(ArryTest[i]); } }
出力
100 101 102 103 104続きを読む