C#

【C#】0(ゼロ)埋めはPadLeftが爆速だった話

アイキャッチ(c_sharp)

こんにちは!
なかむぅです。

この「123」を「00123」にしたいなぁ。

出力された数字や、DBに登録する数字を0埋めしたいときがあると思います。

C#で0埋めする方法は以下の3つ。

  • PadLeft(string型)
  • ToString(int型)
  • string.Format(int型)

それぞれどうやって0埋めするのか、速度はどれが一番早いかなど試してみたのでまとめていきます。

PadLeft(string型)

PadLeftは指定された文字を、指定された文字数になるまで左側に埋め込みます。

右寄せしたいときに使うやつですね。

0埋めしたい数字はstring型が前提です。

埋めたい文字はchar型で指定します。


文字列.PadLeft(文字数, '埋めたい文字');

たとえば

  • Hello! World
  • Hello! C#
  • Hello! .Net

といった3つの文字列を、「Hello! World」に合わせて「#」で右寄せしたい時は以下のように書きます。


static void Main(string[] args)
{
	Console.WriteLine($"{ExecPadLeft("Hello! World")}");
	Console.WriteLine($"{ExecPadLeft("Hello! C#")}");
	Console.WriteLine($"{ExecPadLeft("Hello! .Net")}");
}

private static string ExecPadLeft(string value)
{
	return value.PadLeft(12, '#');
}
結果

Hello! World
###Hello! C#
#Hello! .Net

埋めたい文字を指定せず、桁数だけ渡すと自動的に空白埋めになります。


private static string ExecPadLeft(string value)
{
	return value.PadLeft(12);
}
結果

Hello! World
   Hello! C#
 Hello! .Net

ちなみにPadRightもあります。

なので、「123」のような数字を0埋めしたい時は以下のように書きましょう。


static void Main(string[] args)
{
	Console.WriteLine($"{ExecPadLeft("1")}");
	Console.WriteLine($"{ExecPadLeft("123")}");
	Console.WriteLine($"{ExecPadLeft("12345")}");
}

private static string ExecPadLeft(string value)
{
	return value.PadLeft(5, '0');
}
結果

00001
00123
12345

12345に合わせて「0」が埋められました。

桁数を「7」に変更して、埋めたい文字を「X」にすると以下のように変化します。

好きな桁数と埋めたい文字を変更してみてください。


private static string ExecPadLeft(string value)
{
	return value.PadLeft(7, 'X'); // 7桁にしてX埋めに変更
}
結果

XXXXXX1
XXXX123
XX12345

ToString(int型)

int型に対して0埋めしたいときに使えます。

ToStringの引数に10進数書式指定子を使いましょう。


数値.ToString("10進数書式指定子");

5桁の数字として0埋めしたいときは、以下のように書きます。


static void Main(string[] args)
{
	Console.WriteLine($"{ExecToString(1)}");
	Console.WriteLine($"{ExecToString(123)}");
	Console.WriteLine($"{ExecToString(12345)}");
}

private static string ExecToString(int value)
{
	return value.ToString("D5");
}
結果

00001
00123
12345

「D」のあとに「0」で揃えたい桁数を入れればいいので、7桁にしたいときは「D7」にすると7桁で0埋めしてくれます。


private static string ExecToString(int value)
{
	return value.ToString("D7"); // D7に変更
}
結果

0000001
0000123
0012345

ToStringで10進数書式指定子を使わない方法

ToStringは10進数書式指定子だけでなく、0埋めして統一したい桁数分の「0」を入れることでも可能です。


数値.ToString("桁数分の0");

5桁で揃えたい場合は、引数に「0」を5つ指定します。


private static string ExecToString(int value)
{
	return value.ToString("00000");
}
結果

00001
00123
12345

ただ、この方法だと7桁で揃えたい時は「0」を7つ指定しないといけないので、揃えたい桁数が増えるたびに記述が増えてしまいます。

10進数書式指定子のほうがスッキリ書けるので、この書き方は需要なさそうですね。


private static string ExecToString(int value)
{
	return value.ToString("0000000"); // 「0」を7つに変更
}
結果

0000001
0000123
0012345

0以外は渡した文字列に変換される(余談)

ToStringは「0」でしか埋めることができませんでした。

当たり前の話ですが「1」を指定すると、そのまんま文字列の「11111」として変換されます。


private static string ExecToString(int value)
{
	return value.ToString("11111");
}
結果

11111
11111
11111

もちろん「Hello, World!」にすると全てHello, World!になります。


private static string ExecToString(int value)
{
	return value.ToString("Hello, World!");
}
結果

Hello, World!
Hello, World!
Hello, World!

「そんなの知ってるよ」って感じですが、世の中には

「1」で埋めたいときは、「1」を引数に渡せばいいのか

と思ってしまう人も居るのです。

誰とは言いませんが。

どうしても「0」以外で埋めたい場合はPadLeftを使いましょう。

10進数書式指定子のほうが速い

ToStringは10進数書式指定子を使ったほうが書きやすいですが

どっちが速いんやろう

と思ったので測ってみると、10進数書式指定子を使ったほうが速かったです。


static void Main(string[] args)
{
	// 順番を変更すると結果が変わるので、コメントアウトして1つ1つ実行
	IntMeasurement(ExecToStringD5);
	IntMeasurement(ExecToString05);
}

private static string ExecToStringD5(int value)
{
	return value.ToString("D5");
}

private static string ExecToString05(int value)
{
	return value.ToString("00000");
}

private static int _length = 100000;
private static void IntMeasurement(Func<int, string> exe)
{
	var zeroPaddingList = new List<string>();
	var sw = new Stopwatch();
	sw.Start();
	for (int i = 0; i < _length; i++)
	{
		zeroPaddingList.Add(exe(i));
	}
	sw.Stop();

	Console.WriteLine($"{exe.Method.Name} : {sw.Elapsed}");
}
結果

ExecToStringD5 : 00:00:00.0054231
ExecToString05 : 00:00:00.0166016

string.Format(int型)

string.Formatで0埋めする方法もあり、ToString同様に10進数書式指定子を使います。


string.Format("{0:10進数書式指定子}", 数値);

string.Formatだと以下のような書き方になります。


static void Main(string[] args)
{
	Console.WriteLine($"{ExecStringFormat(1)}");
	Console.WriteLine($"{ExecStringFormat(123)}");
	Console.WriteLine($"{ExecStringFormat(12345)}");
}

private static string ExecStringFormat(int value)
{
	return string.Format("{0:D5}", value);
}
結果

00001
00123
12345

もちろんToString同様、0埋めして統一したい桁数分の「0」を入れることでも0埋めが可能です。


string.Format("{0:桁数分の0}", 数値);

5桁で0埋めしたい場合は以下のように書きます。


private static string ExecStringFormat(int value)
{
	return string.Format("{0:00000}", value);
}
結果

00001
00123
12345

速度も10進数書式指定子を使ったほうが速かったです。

コードは省略。

結果

ExecStringFormatD5 : 00:00:00.0116967
ExecStringFormat05 : 00:00:00.0231988

PadLeft、ToString、string.Formatの速度

やっぱり最後は

どれが一番速いんや

となったので、測ってみました。


static void Main(string[] args)
{
	// 順番を変更すると結果が変わるので、コメントアウトして1つ1つ実行
	StringMeasurement(ExecPadLeft);
	IntMeasurement(ExecToString);
	IntMeasurement(ExecStringFormat);
}

private static string ExecPadLeft(string value)
{
	return value.PadLeft(5, '0');
}

private static string ExecToString(int value)
{
	return value.ToString("D5");
}

private static string ExecStringFormat(int value)
{
	return string.Format("{0:D5}", value);
}

private static int _length = 100000;
private static void StringMeasurement(Func<string, string> exe)
{
	// string型なのでstringのListを作成する
	var list = GetStringList();
	var zeroPaddingList = new List<string>();
	var sw = new Stopwatch();
	sw.Start();
	for (int i = 0; i < list.Count; i++)
	{
		zeroPaddingList.Add(exe(list[i]));
	}
	sw.Stop();

	Console.WriteLine($"{exe.Method.Name} : {sw.Elapsed}");
}

private static List<string> GetStringList()
{
	var list = new List<string>();
	for (int i = 0; i < _length; i++)
	{
		list.Add(i.ToString());
	}
	return list;
}

private static void IntMeasurement(Func<int, string> exe)
{
	var zeroPaddingList = new List<string>();
	var sw = new Stopwatch();
	sw.Start();
	for (int i = 0; i < _length; i++)
	{
		zeroPaddingList.Add(exe(i));
	}
	sw.Stop();

	Console.WriteLine($"{exe.Method.Name} : {sw.Elapsed}");
}
結果

ExecPadLeft      : 00:00:00.0021107
ExecToString     : 00:00:00.0054231
ExecStringFormat : 00:00:00.0116967

PadLeftが優勝。

とはいえ環境や処理によって変わるかもしれないので、気になる方はご自身で測ってみてください。


私の会社で一緒に働きませんか?

私が働く会社では、一緒に働いてくれるエンジニアを募集しています♪

こんな人がオススメ
  • 長く働いていても年収が全然上がらない…一気に年収を上げたい
  • 残業をしたくてしているわけではないので、残業代はしっかりと出して欲しい
  • やりたいことに挑戦させてもらえない…自分がしてみたいことに挑戦したい
  • 通勤時間が長すぎるから、できるだけ短くしたい
  • もっと勉強したいから、書籍代や資格の受験料など負担してくれるところに入りたい
  • 現場に駆り出されてからは放置プレイ…相談できる人も先輩も居ないので、自分の状況をちゃんと理解してくれるところで働きたい

上記内容に1つでも当てはまる場合は、ぜひお声がけください。
私のサイトから応募していただいた方にはお好きなギフト券5000円分プレゼントさせていただきます(条件あり)。

詳細ページ


まとめ

  • C#で0埋めしたいときはPadLeft、ToString、string.Formatの3つの方法で行える
  • 速度はPadLeftが一番速い
いやここは違うだろ

と思った方はコメントいただけると嬉しいです。

記事で検証したこと以外にも気になることがあればコメントお願いします。

最後までお読みいただきありがとうございました!

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です