拡張メソッドで遊んでみた。
配列内の全ての値がユニークであるかを調べるメソッド「IsUniq」だすぅ。
code-1
//loop 1E6 -> 176ms
public static bool IsUniq<T>(this T[] source)
{
for (int i = 0; i < source.Length - 1; i++)
{
if (Array.IndexOf(source, source[i], i + 1) != -1)
{
return false;
}
}
return true;
}
code-2
//非破壊的ソート
public static T[] Sort<T>(this T[] source)
{
T[] clone = (T[])source.Clone();
Array.Sort(clone);
return clone;
}
//loop 1E6 -> 455ms
public static bool IsUniq<T>(this T[] source)
{
T[] clone = source.Sort();
for (int i = 0, j = clone.Length - 1; i < j; i++)
{
if (clone[i].Equals(clone[i + 1]))
{
return false;
}
}
return true;
}
非破壊的ソートメソッドを書き足したのだが、そのせい(?)でパフォーマンスが今一つ。code-3
//loop 1E6 -> 2050ms
public static bool IsUniq<T>(this T[] source)
{
for (int i = 0; i < source.Length - 1; i++)
{
T tmp = source[i];
if (source.Skip(i + 1).ToArray().Any((item) => tmp.Equals(item)))
{
return false;
}
}
return true;
}
Linqを使ってコードを少々シンプルにした。やろうとしていることは「
code - 1」に近いかな?パフォーマンス的に論外。
code-4
//loop 1E6 -> 145ms
public static bool IsUniq<T>(this T[] source, Func<T, T, bool> comparer)
{
int length = source.Length;
for (int i = 0, j = length - 1; i < j; i++)
{
T currentItem = source[i];
for (int n = i + 1; n < length; n++)
{
if (comparer(currentItem, source[n]))
{
return false;
}
}
}
return true;
}
これが一番パフォーマンスが良い結果になった。Usage
int[] arr = { 12, 34, 56, 78, 90};
bool ret = arr.IsUniq();
//or
//bool ret = arr.IsUniq((x, y) => x == y);
ここからは御ふざけで御座います。
Distinctを使う。//loop 1E6 -> 787ms
public static bool IsUniq<T>(this T[] source)
{
return source.Length == ((T[])source.Clone()).Distinct().Count();
}
やはり、配列コピーしたりLinqメソッド使うと重くなるよね。Whereを使う。//loop 1E6 -> 1615ms
public static bool IsUniq<T>(this T[] source)
{
for (int i = 0; i < source.Length - 1; i++)
{
T tmp = source[i];
if (source.Skip(i + 1).Where((item) => tmp.Equals(item)).Count() > 0)
{
return false;
}
}
return true;
}
お話になりません。Allを使う//loop 1E6 -> 1380ms
public static bool IsUniq<T>(this T[] source)
{
for (int i = 0; i < source.Length - 1; i++)
{
T tmp = source[i];
if (!source.Skip(i + 1).All((item) => !tmp.Equals(item)))
{
return false;
}
}
return true;
}
...飽きた。





0 Comments:
コメントを投稿