0

膨大なレガシー コード ベースがあり、それを最適化し、高速化したいと考えています。このため、リストと配列を HashSets と Dictionaries に置き換える機会を探すことを考えました。

.NET Framework Usage / System.collection の下に、次の NDepend クエリがあります。

// <Name>Caution with List.Contains()</Name>
let containsMethods = ThirdParty.Methods.WithFullNameIn(
   "System.Collections.Generic.List<T>.Contains(T)",
   "System.Collections.Generic.IList<T>.Contains(T)",
   "System.Collections.ArrayList.Contains(Object)")

from m in Application.Methods.UsingAny(containsMethods) 
select m

このクエリでは不十分です。次のコードで 1 つの関数がリストされます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ListOptimisation
{
    class Program
    {
        static void Main(string[] args)
        {
            int aLength = 10000;
            List<int> aNumbers2Search = Enumerable.Range(0, aLength).ToList();

            List<int> aTestList = Enumerable.Range(0, aLength).ToList();
            int[] aTestArray = Enumerable.Range(0, aLength).ToArray();

            HashSet<int> aTestHash = new HashSet<int>(Enumerable.Range(0, aLength));
            Dictionary<int, int> aTestDictionary = new Dictionary<int, int>();
            for(int i = 0; i < aLength; ++i)
            {
                aTestDictionary.Add(i, i);
            }

            Search(aTestList, aNumbers2Search);
            SearchIList(aTestList, aNumbers2Search);
            SearchIEnumerable(aTestList, aNumbers2Search);
            Search(aTestArray, aNumbers2Search);
            SearchIList(aTestArray, aNumbers2Search);
            SearchIEnumerable(aTestArray, aNumbers2Search);
            Search(aTestHash, aNumbers2Search);
            SearchIEnumerable(aTestHash, aNumbers2Search);
            Search(aTestDictionary, aNumbers2Search);
        }

        private static void Search(List<int> testList_in, List<int> numbers2Search_in)
        {
            numbers2Search_in.ForEach(x => testList_in.Contains(x));
        }

        private static void Search(HashSet<int> testHash_in, List<int> numbers2Search_in)
        {
            numbers2Search_in.ForEach(x => testHash_in.Contains(x));
        }

        private static void Search(Dictionary<int, int> testDictionary_in, List<int> numbers2Search_in)
        {
            numbers2Search_in.ForEach(x => testDictionary_in.ContainsKey(x));
        }

        private static void Search(int[] testArray_in, List<int> numbers2Search_in)
        {
            numbers2Search_in.ForEach(x => testArray_in.Contains(x));
        }

        private static void SearchIList(IList<int> testIList_in, List<int> numbers2Search_in)
        {
            numbers2Search_in.ForEach(x => testIList_in.Contains(x));
        }

        private static void SearchIEnumerable(IEnumerable<int> testIEnumerable_in, List<int> numbers2Search_in)
        {
            numbers2Search_in.ForEach(x => testIEnumerable_in.Contains(x));
        }
    }
}

より良いクエリは次のとおりです。

// <Name>Caution with List style contains</Name>
let containsMethods = ThirdParty.Methods.WithSimpleName("Contains").Except(ThirdParty.Methods.WithFullNameIn("System.Collections.Generic.HashSet<T>.Contains(T)"))

from m in Application.Methods.UsingAny(containsMethods) 
select m

//<Description>
// Alternative to Caution with List.Contains()
//</Description>

これにより、4 つの関数 (List、IList、int[]、IEnumerable) がリストされます。私はCQLinqに関して初心者です。私の質問は次のとおりです。

  • 不適切な .NET コンテナーの使用法 (contains だけでなく、他の可能な操作) を検出するためのより良いクエリを作成できる人はいますか?
  • コンテナの不適切な使用をどのように検出しますか?

最後のコメントとして、一部のビジネス ロジックは大量のデータを処理するため、適切なコンテナー、データ構造、およびアルゴリズムが重要になります。

4

2 に答える 2

1

これは、パフォーマンスの問題を最適化するための適切なアプローチではありません。巨大なリストを扱っていない限り、この最適化はシステムにわずかな影響しか与えません。

パフォーマンス プロファイリング ソフトウェアを使用すると、より良い結果が得られます。コード パターンを検索してパフォーマンスを向上させたい場合は、ネストされたループや、ファイルやデータベース関連のメソッドなどの高価なコードを検索してみてください。

于 2016-07-22T17:53:15.823 に答える