Skip to content

Instantly share code, notes, and snippets.

@juner
Last active September 27, 2017 05:07
Show Gist options
  • Save juner/e39860fbe0b15ec59d0961398fd92f24 to your computer and use it in GitHub Desktop.
Save juner/e39860fbe0b15ec59d0961398fd92f24 to your computer and use it in GitHub Desktop.
配列に入ったbyte要素が全て0でないことを比較するループの最速解を求める為にコーディングして速度比較していたときのコードのメモ ref: http://qiita.com/juner/items/1a80eb0e320fe30fd6b7
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