2017年11月29日水曜日

バッチで自身のパスに移動する

バッチファイル自身のパスに移動する理由


バッチファイルをダブルクリックで実行した場合には、バッチファイルのパスがカレントディレクトリになります。
しかし、コマンドラインから実行した場合には、実行場所がカレントディレクトリになってしまいます。

基本的には、問題ないのですが、
バッチファイルから相対パスにあるバッチファイルを呼び出す場合には、自分自身の場所を知っておく必要があります。

コマンド

cd %~dp0

※cd コマンドで /dを追加するとドライブの移動も可能。
cd /d %~dp0

説明


「%0」や「%1」・・・には、引数が渡されています。その中で、「%0」はバッチファイル自身のパスが含まれています。

「~」チルダは、そのパスの「”」ダブルクォーテーションを取り除きます。
「d」は、ドライブ名「C:\」を表示します。
「p」は、パス名を表示します。

2017年11月23日木曜日

Kotlinの引数の書き方(基本)


引数の省略


引数は、省略された場合に使用するデフォルト値を持つことが可能です。
デフォルト値は、値の後ろに=をつけて記載します。

fun removeCounnt(cnt: Int = 1) {}

名前付き引数


関数を呼び出す際に、名前付きでパラメーターを指定することが可能です。

定義
fun append(str1: String,str2: String) {}

呼び出し
append(str1 = "Hello", str2 = "World!" )

Kotlinの関数の書き方については、以前の投稿を参照。

Kotlinの関数の書き方(基本)


関数


Kotlinでは、関数は、funキーワードを使用して宣言します。

書き方は、
fun 関数名(変数名:変数型,...)戻り値型

です。
四則演算を例にすると、

fun add(data1:Int, data2:Int) :Int
{
    return data1 + data2;
}

関数の戻り値

Kotlinでは、関数は、必ず、戻り値を返します。

以下の3つは同じ意味になります。

fun add(data1:Int, data2:Int) :Unit
{
    var data = data1 + data2;
    return
}

fun add(data1:Int, data2:Int)
{
    var data = data1 + data2;
    return
}

fun add(data1:Int, data2:Int)
{
    var data = data1 + data2;
}

Kotlin Refrenceを参照して、内容をまとめています。

2017年11月21日火曜日

文字列比較の速度を比べてみる


検証内容

文字列の一致についてどれが一番早いかを比較。
調査する種類は、以下の3つとする


  • String.CompareTo
  • ==演算子
  • String.Compare




検証コード

static void StringCompare()
{
    var count = 100000;
    var ret = false;
    var inputStr1 = "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789";
    var inputStr2 = "abCdEfGhIjKlMnOpQrStUvWxYz0123456789";
    Console.WriteLine("---------------------------------");
    Console.WriteLine($"ループ回数:{count:d}");

    //-----------------------------------------------------------------
    var time = Stopwatch.StartNew();
    for (var i = 0; i < count; i++)
    {
        ret = inputStr1.ToLower().CompareTo(inputStr2.ToLower()) ==0;
    }
    time.Stop();
    Console.WriteLine($"CompareTo : {time.ElapsedMilliseconds}ms");

    //-----------------------------------------------------------------
    time.Restart();
    for (var i = 0; i < count; i++)
    {
        ret = (inputStr1.ToLower() == inputStr2.ToLower());
    }
    time.Stop();
    Console.WriteLine($"== : {time.ElapsedMilliseconds}ms");

    //-----------------------------------------------------------------
    time.Restart();
    for (var i = 0; i < count; i++)
    {
        ret = String.Compare(inputStr1 ,inputStr2,true) == 0;
    }
    time.Stop();
    Console.WriteLine($"String.Compare : {time.ElapsedMilliseconds}ms");
}

結果

---------------------------------
ループ回数:100000
CompareTo : 108ms
== : 74ms
String.Compare : 104ms
---------------------------------
ループ回数:100000
CompareTo : 112ms
== : 61ms
String.Compare : 79ms
---------------------------------
ループ回数:100000
CompareTo : 88ms
== : 47ms
String.Compare : 77ms
---------------------------------
ループ回数:100000
CompareTo : 105ms
== : 61ms
String.Compare : 81ms
---------------------------------
ループ回数:100000
CompareTo : 103ms
== : 45ms
String.Compare : 99ms

結論

==演算子が速い!!
でも、10万回も回しての数十msなら、どちらでもよいかも。
っていうか、こちらについても相当シビアな環境じゃなきゃ影響なし。

2017年11月20日月曜日

C#で文字が含まれるかどうかの判定速度を比較してみた


検証内容

文字列の中から、1文字(char)が含まれるかどうかを調べる。
調査する種類は、以下の4つ


  • Contains("文字列")
  • Contains('文字')
  • IndexOf("文字列")
  • IndexOf('文字')


検証コード


static void TestContains()
{
    var count = 100000;
    var ret = false;
    var inputStr = "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefg";
    Console.WriteLine("---------------------------------");
    Console.WriteLine($"ループ回数:{count:d}");
    var time = Stopwatch.StartNew();
    for (var i = 0; i < count; i++)
    {
        ret = inputStr.Contains("g");
    }
    time.Stop();
    Console.WriteLine($"Contains(\"g\") : {time.ElapsedMilliseconds}ms");
    time.Restart();
    for (var i = 0; i < count; i++)
    {
        ret = inputStr.Contains('g');
    }
    time.Stop();
    Console.WriteLine($"Contains('g') : {time.ElapsedMilliseconds}ms");
    time.Restart();
    for (var i = 0; i < count; i++)
    {
        ret = inputStr.IndexOf("g") > 0;
    }
    time.Stop();
    Console.WriteLine($"IndexOf(\"g\") : {time.ElapsedMilliseconds}ms");
    time.Restart();
    for (var i = 0; i < count; i++)
    {
        ret = inputStr.IndexOf('g') > 0;
    }
    time.Stop();
    Console.WriteLine($"IndexOf('g') : {time.ElapsedMilliseconds}ms");
}

結果

ループ回数:100000
Contains("g") : 39ms
Contains('g') : 113ms
IndexOf("g") : 432ms
IndexOf('g') : 8ms
---------------------------------
ループ回数:100000
Contains("g") : 29ms
Contains('g') : 115ms
IndexOf("g") : 417ms
IndexOf('g') : 7ms
---------------------------------
ループ回数:100000
Contains("g") : 30ms
Contains('g') : 115ms
IndexOf("g") : 300ms
IndexOf('g') : 5ms
---------------------------------
ループ回数:100000
Contains("g") : 27ms
Contains('g') : 80ms
IndexOf("g") : 287ms
IndexOf('g') : 4ms
---------------------------------
ループ回数:100000
Contains("g") : 23ms
Contains('g') : 74ms
IndexOf("g") : 335ms
IndexOf('g') : 6ms

結論

1文字の検索なら、IndexOfが速い!!
でも、10万回も回しての数百msなら、どちらでもよいかも。
っていうか、Contains("文字列")でもそこそこ速いから、相当シビアな環境じゃなきゃ影響なし。

2017年11月19日日曜日

C#でStringBuilderと+= 演算子の速度比較をしてみた


概要

StringBuilderと+= 演算子の速度差が気になったので、実験してみました。
方法としては、以下のテストコードを5回繰り返し、結果を確認しています。

テストコード

static void TestAppendText()
{
    var count = 100000;
    Console.WriteLine("---------------------------------");
    Console.WriteLine($"ループ回数:{count:d}");
    var time = Stopwatch.StartNew();
    var message = string.Empty;
    var append = @"append";
    for (var i = 0; i < count; i++)
    {
        message += append;
    }
    time.Stop();
    Console.WriteLine($"String += : {time.ElapsedMilliseconds}ms");
    time.Restart();
    var builderMessage = new StringBuilder();
    for (int i = 0; i < count; i++)
    {
        builderMessage.Append(append);
    }
    time.Stop();
    Console.WriteLine($"StringBuilder: {time.ElapsedMilliseconds}ms");
}

結果

---------------------------------
ループ回数:100000
String += : 23382ms
StringBuilder: 1ms
---------------------------------
ループ回数:100000
String += : 22175ms
StringBuilder: 1ms
---------------------------------
ループ回数:100000
String += : 23060ms
StringBuilder: 1ms
---------------------------------
ループ回数:100000
String += : 23978ms
StringBuilder: 1ms
---------------------------------
ループ回数:100000
String += : 22435ms
StringBuilder: 2ms

結論

明らかに、StringBuilderを使用したほうが早いという結果になりました。
やっぱり、StringBuilderのほうが早くていいよね。+=はだめだね。っていう結論にしてもいいのですが、
試しにループ回数を100回にした場合には、以下の結果になっています。

---------------------------------
ループ回数:100
String += : 0ms
StringBuilder: 0ms

ms単位での差が分かりません。
なので100回程度の文字列の連結であれば、どちらも気にならないと思います。
そもそも、文字列を10万回も結合しなければいけないコードを書く人が悪いと思います。

結論としては、StringBuilderをお勧めはするけど、強要はしないって感じでしょうかねぇ。

2017年11月16日木曜日

Windows10Upgradeフォルダーってなんだ?

気が付いたら、SurfaceProのCドライブの容量が5GBを下回っていた。
びっくりして、調べてみたら、
「C:\Windows10Upgrade」フォルダーなるものがあったので、調べてみた。


Windows10Upgrade

windows10アップグレートアシスタントがインストールされているらしい。

windows10アップグレートアシスタントってなんぞや

Windows10のアップデート時に勝手にインストールされることがあるらしい。
今回は、

Anniversary Update
の関係で、インストールされたっぽい。。。

なんか、Microsoftのコミュニティに記載があった。
# 日本語のURLって好きになれないけど。。。