Help us understand the problem. What is going on with this article?

学校でチーム分けの方法を考えていたら脱線した(日記)

More than 1 year has passed since last update.

まず断っておきますが、これは日記です。日記ですよ。はい。すごく暇なときにどうぞ。ちゃんとプログラムに関する話題は出てきます。

こんなことがありました

筆者は学生なのですが、今度の学校行事の関係で、クラスを10グループに分けなければいけないのです。そこで、どんなチーム分けの方法がいいかという(無駄な)話し合いをすることになりました。なんでや...😞

みんなが、どうすれば均等に分けられるか考えている間、私は「しっているぞ こんなときはプログラムを書いてだな...乱数を使ってウンチャラカンチャラ...ぼくはくわしいんだ」などと考えていたわけです(本当に詳しいだなんて思ってないです)。

そして、発表の時間になって、司会さんがみんなの意見を聞いて行く中で、こんな意見が出たのです。「お財布の中の合計金額を使って分けてみたらいいのではないか(一部脚色)」例えば、Aさんは892円持っていて、Bさんは9980円持っているとします。これらの数値を使って、チーム分けをしようというのです。なかなか斬新な考えですね!?

斬新ですが、合計金額の多い順で、1から10まで順番に番号を振っていって...、という方法でチーム分けをするというのは、教育上あまりいいとは思えません。バッドアイデアです。

名案(名案とは言っていない)を思いついた

そこで、私は、合計金額という斬新なアイデアを採用しつつ、チーム分けをする方法を考えました。「合計金額を10で割った余りをグループ番号にすればいいのではないか」と。

お財布を忘れた?人数が均等にならなそう?細けぇこたぁ気にすんな(`・ω・´) 

ということで(?)この方法を、近くの席のクラスメイトに話してみました。すると、数秒してから、こんな答えが返ってきました。「つまり、下1桁の数字ってこと?」

......確かにそうとも言いますね。その説明の方が、多くの人にとって分かりやすいかも知れません。しかし、偉い人は言いました。「人間にとって分かりやすいことと、コンピューターにとって分かりやすいことは、同じとは限らない(超意訳)」のだと。

プログラマーとして...

私もプログラマーの端くれです。ここは、10で割った余りスタイル と 下1桁の数字スタイル でどっちの実行速度が速いのか確かめなければなりません(落ち着け)(謎の使命感)。話し合いの結果、合計金額案はボツになったので、みんなの合計金額のデータは手元にありません...ならば、作ればいいのです!

ということで作りました。

random.cs
using System;
public class Hello{
    public static void Main(){

        var seed = Environment.TickCount;

        for(int i = 0; i < 10000; i++)
        {
            //毎回シード値を変更して、
            //1以上100000未満の整数(乱数のようなもの)を生成する
            Random r = new Random(seed++);
            var num = r.Next(1,100000);

            //生成した乱数のようなものを出力して、
            //区切り文字としてスペースも出力する
            Console.Write(num + " ");
        }

    }
}

追記
random.csによって生成される数字を乱数と表記していましたが、正確には乱数のようなものであり、乱数ではありませんでした。

こんな感じでいいでしょう。実行速度の違いが分かりやすいように、クラスメイトは1万人いることにしました。過密!過密!圧倒的過密!

それでは、このプログラムによって得られた1万人分の所持合計金額のデータを入力値として、10で割った余り VS 下1桁の数字 対決をしましょう。

たいけつだ!

ルール:入力されたデータを、Split()を使ってstring型の配列に格納するところまでは共通とする。

赤コーナー:10で割った余りスタイル

main1.cs
using System;
public class Hello{
    public static void Main(){

        DateTime start, end;

        //string型の配列に1つ1つ格納
        string[] str = Console.ReadLine().Split(' ');

        //計測開始
        start = DateTime.Now;

        for(int i = 0; i < 10000; i++)
        {
            //配列strの中身をint型に変換してから
            //10で割った余りを出力する
            Console.Write(int.Parse(str[i]) % 10 + " ");
        }

        //計測終了
        end = DateTime.Now;

        Console.WriteLine();

        //処理にかかった時間を秒単位で出力
        Console.WriteLine((end - start).TotalSeconds);
    }
}

説明は、コメント文に書いた通りです。これは勝てそう!(フラグ)

青コーナー:下1桁の数字スタイル

main2.cs
using System;
public class Hello{
    public static void Main(){

        DateTime start, end;

        //string型の配列に1つ1つ格納
        string[] str = Console.ReadLine().Split(' ');

        //計測開始
        start = DateTime.Now;

        for(int i = 0; i < 10000; i++)
        {
            //配列strのi番目の要素の、
            //配列strのi番目の要素の文字列の長さ - 1 番目の文字を出力する
            Console.Write(str[i][str[i].Length - 1] + " ");

        }

        //計測終了
        end = DateTime.Now;

        Console.WriteLine();

        //処理にかかった時間を秒単位で出力
        Console.WriteLine((end - start).TotalSeconds);
    }
}

str[i][str[i].Length - 1]のところがヤバい。

集計しよう

ということで実行時間を集計していきます。今回はpaiza.io にて計測しました。10回ずつ交互に計測し、平均を取りました。最大値と最小値もあります。結果はこのようになりました。

image.png

結果発表

今回の計測では、10で割った余りスタイルよりも、下1桁の数字スタイルの方が処理が速いという結果になりました。確かに、10で割った余りスタイルの「string型からint型に変換して、それを10で割った余りを出力する」よりも、下1桁の数字スタイルの「各配列の要素に直接アクセスする」方が速そうな気がしますね。

まとめ

【悲報】10で割った余りスタイルさん
人に伝わりにくいだけでなく、実行速度の面でも敗北か/(^o^)\ /(^o^)\

感想

今回はpaiza.io さんで計測しましたが、Visual Studioとかで計測してみようと思いました。また、pythonやRubyなどのC#以外の言語でも同じ結果になるのか気になりました。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away