Last active
September 27, 2017 05:07
-
-
Save juner/e39860fbe0b15ec59d0961398fd92f24 to your computer and use it in GitHub Desktop.
配列に入ったbyte要素が全て0でないことを比較するループの最速解を求める為にコーディングして速度比較していたときのコードのメモ ref: http://qiita.com/juner/items/1a80eb0e320fe30fd6b7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace ArrayTest | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var bytes = new byte[512000]; | |
DateTime Time; | |
var MAX = 1000; | |
var sum = TimeSpan.Zero; | |
// 配列として0チェック(foreach版) | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkArray(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkArray)}:{sum.TotalMilliseconds / MAX}ms"); | |
// 配列として0チェック(for版) | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkArray2(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkArray2)}:{sum.TotalMilliseconds / MAX}ms"); | |
// IEnumerableとして0チェック | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkEnumerable(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkEnumerable)}:{sum.TotalMilliseconds / MAX}ms"); | |
// Enumerable.Anyとして0チェック | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
bytes.Any((v) => v != 0); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(Enumerable.Any)}:{sum.TotalMilliseconds / MAX}ms"); | |
// Enumerable.Allとして0チェック | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
bytes.All((v) => v == 0); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(Enumerable.All)}:{sum.TotalMilliseconds / MAX}ms"); | |
// unchecked下で forで0チェックを行う | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkArray3(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkArray3)}:{sum.TotalMilliseconds / MAX}ms"); | |
// uncheckを使用した上でforで0方向による0チェックを行う | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkArray4(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkArray4)}:{sum.TotalMilliseconds / MAX}ms"); | |
// unsafeを用いて ポインタによる0チェックを行う | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkArray5(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkArray5)}:{sum.TotalMilliseconds / MAX}ms"); | |
// unsafeを用いて long間隔で0チェックを行う | |
sum = TimeSpan.Zero; | |
Time = DateTime.Now; | |
for (var i = 0; i < MAX; i++) | |
{ | |
checkArray6(bytes); | |
} | |
sum += DateTime.Now - Time; | |
Console.WriteLine($"{nameof(checkArray6)}:{sum.TotalMilliseconds / MAX}ms"); | |
Console.ReadLine(); | |
} | |
/// <summary> | |
/// 配列を0以外がくるまで回す。0以外が来ればfalse/そうでなければtrueを返す | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkArray(byte[] bytes) | |
{ | |
foreach (var b in bytes) | |
if (b != 0) | |
return false; | |
return true; | |
} | |
/// <summary> | |
/// 配列を0以外がくるまで回す。0以外が来ればfalse/そうでなければtrueを返す | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkArray2(byte[] bytes) | |
{ | |
var imax = bytes.Length; | |
for (var i = 0; i < imax; i++) | |
{ | |
var b = bytes[i]; | |
if (b != 0) | |
return false; | |
} | |
return true; | |
} | |
/// <summary> | |
/// 配列を0以外がくるまで回す。0以外が来ればfalse/そうでなければtrueを返す | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkEnumerable(IEnumerable<byte> bytes) | |
{ | |
foreach (var b in bytes) | |
if (b != 0) | |
return false; | |
return true; | |
} | |
/// <summary> | |
/// unchecked下で byteを0チェックする | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkArray3(byte[] bytes) | |
{ | |
var imax = bytes.Length; | |
unchecked | |
{ | |
for (int i = 0; i < imax; i++) | |
{ | |
if (bytes[i] != 0) | |
return false; | |
} | |
return true; | |
} | |
} | |
/// <summary> | |
/// uncheckを使用した上でforで0に向かった方向で0チェックを行う | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkArray4(byte[] bytes) | |
{ | |
unchecked | |
{ | |
for (int i = bytes.Length - 1; i >= 0; i--) | |
{ | |
if (bytes[i] != 0) | |
return false; | |
} | |
return true; | |
} | |
} | |
/// <summary> | |
/// unsafeを使って ポインタを使った0チェックを行う | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkArray5(byte[] bytes) | |
{ | |
var imax = bytes.Length; | |
unchecked | |
{ | |
unsafe | |
{ | |
fixed (byte* p = &bytes[0]) | |
{ | |
for (int i = 0; i < imax; i++) | |
{ | |
if (*(p + i) != 0) | |
return false; | |
} | |
} | |
return true; | |
} | |
} | |
} | |
/// <summary> | |
/// byte[]を long[]として0かどうかをチェックする | |
/// </summary> | |
/// <param name="bytes"></param> | |
/// <returns></returns> | |
static bool checkArray6(byte[] bytes) | |
{ | |
var imax = bytes.Length / 8; | |
var あまり = bytes.Length % 8; | |
unchecked | |
{ | |
unsafe | |
{ | |
fixed (byte* p = &bytes[0]) | |
{ | |
var intp = (Int64*)p; | |
for (int i = 0; i < imax; i++) | |
{ | |
if (*(intp + i) != 0) | |
return false; | |
} | |
} | |
if (あまり > 0) | |
{ | |
fixed (byte* p = &bytes[imax * 8]) | |
{ | |
for (int i = 0; i < あまり; i++) | |
{ | |
if (*(p + i) != 0) | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment