漫坊亭

社会の底辺プログラマ

秩父夜祭2015

恒例の秩父夜祭に行ってきた。 昨年は、12/4休まなかったんだけど、なんかつまんなかったんだよね。 せわしないというか、翌日を考えて疲れないようにしていたら、とてもつまらなかった。 なので、今年は休みにしたよ。 おかげで4連休になったけど。

f:id:jfactory:20160204141257j:plain

ますます会社に居づらくなったな(www

ゲームプログラマのためのコーディング技術

f:id:jfactory:20160204141124j:plain

タイトルは「ゲームプログラマ」だが、C++11/14の効率のよいプログラミングの本である。

前半は実装技術、後半は設計技術が書かれている。

実装技術は、わかりやすいコーディング技術や、メンテしやすくする方法について触れている。 設計技術は、デザインパターンや、クラス設計について触れている。 いずれも、もっと詳しい本はいろいろあるが、実例を通してサラッと記述している部分が評価できる。

Effective C++ 第3版 / Effective Modern C++

Effective C++ 第3版

f:id:jfactory:20160204140812j:plain

Boostを使っていれば、「あ、これも標準に入ったのか」と思うだろう。 BindとかFunctionも取り込まれているんだな。 第4版が出ても、たぶん読むだろう。

Effective Modern C++

f:id:jfactory:20160204140849j:plain

小難しく書いてあり、あまり面白くない。
なぜ、そう書かなくてはならないかは解るが、もう少し上手い書き方はないだろうか。
moveコンストラクタは勉強になったが、いままで、copyコンストラクタのオーバーヘッドは意識していなかったので、きっとこれからも意識しないだろう。cpuはハイパワーだし、そんな大きいクラスは作らなければ(神クラスは悪!)、問題なさげ。
const汚染について、もう少し掘り下げて欲しかった。

Enum.HasFlagの速度

google先生が、Enum.HasFlagはBoxing/Unboxingが発生するので遅い、とおっしゃるので、速度を計ってみた。ついでに、Parallelも使ってみた。

for版

回 数 bit演算 HasFlag 総検査時間
1,000,000 18 148 1,673
10,000,000 169 1,299 14,689
100,000,000 1,688 12,756 144,267

総じて、8倍くらいの時間がかかるようだ。

Parallelで回してみると、総検査時間が1/3くらいになる。
bit演算とHasFlagの速度比が、4倍くらいに縮まっているのは謎だが。

Parallel.For版

回 数 bit演算 HasFlag 総検査時間
1,000,000 14 55 696
10,000,000 106 492 5,552
100,000,000 835 3,501 47,213
  • for版のタスクマネージャ f:id:jfactory:20160204140148p:plain

  • Parallel.For版のタスクマネージャ f:id:jfactory:20160204140204p:plain

Parallelのほうが、CPUをまんべんなく使っているのがわかる。

namespace EnumHasFlagTest
{
    [Flags]
    public enum TestFlag
    {
        A = 1,
        B = 2,
        C = 4,
        D = 8, 
    }

    class Program
    {
        static long Meas(int count, Action func)
        {
            var sw = Stopwatch.StartNew();
            for (int i = 0; i < count; i++)
            {
                func();
            }

            return sw.ElapsedMilliseconds;
        }

        static void FuncBitComp()
        {
            var flags = TestFlag.B | TestFlag.D;
            var a1 = (flags & TestFlag.A) == TestFlag.A;
            var a2 = (flags & TestFlag.B) == TestFlag.B;
            var a3 = (flags & TestFlag.C) == TestFlag.C;
            var a4 = (flags & TestFlag.D) == TestFlag.D;

        }
        static void FuncHasFlag()
        {
            var flags = TestFlag.B | TestFlag.D;
            var a1 = flags.HasFlag(TestFlag.A);
            var a2 = flags.HasFlag(TestFlag.B);
            var a3 = flags.HasFlag(TestFlag.C);
            var a4 = flags.HasFlag(TestFlag.D);
        }

        static void Main(string[] args)
        {
            int count = 100000000;
            long a = 0, b = 0;

            var sw = Stopwatch.StartNew();
            
            //// Parallel.For版
            Parallel.For(0, 10, (x) =>
            {
                a += Meas(count, FuncBitComp);
                b += Meas(count, FuncHasFlag);
            });

            //// for版
            //for(int i = 0; i < 10; i++)
            //{
            //    a += Meas(count, FuncBitComp);
            //    b += Meas(count, FuncHasFlag);
            //}

            Console.WriteLine("{0}ms", sw.ElapsedMilliseconds);

            Console.WriteLine("BitComp={0}", a / 10);
            Console.WriteLine("HasFlag={0}", b / 10);

            Console.ReadLine();
        }
    }
}

Debug.WriteLineが出力されない?

private void button1_Click(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("Debug");
    System.Diagnostics.Trace.WriteLine("Trace");
    System.Console.WriteLine("Console");
}

出力ウィンドウには、Cosoleしか表示されないぞ??

f:id:jfactory:20160204135723p:plain

実は、イミディエイトウィンドウに表示されているのであった。