拡張メソッドで遊んでみた。
配列内の全ての値がユニークであるかを調べるメソッド「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:
コメントを投稿