0

本にインデックスを付け、そのインデックスでブールテキスト取得アルゴリズムを実行する小さなC#アプリケーションを作成しました。投稿の最後にあるクラスは、両方の実装、インデックスの作成、およびその上でのアルゴリズムの実行を示しています。

コードは、次の方法でGUIボタンを介して呼び出されます。

    private void Execute_Click(object sender, EventArgs e)
    {
        Stopwatch s;
        String output = "-----------------------\r\n";

        String sr = algoChoice.SelectedItem != null ? algoChoice.SelectedItem.ToString() : "";

        switch(sr){
            case "Naive search":
                output += "Naive search\r\n";
                algo = NaiveSearch.GetInstance();
                break;
            case "Boolean retrieval":
                output += "boolean retrieval\r\n";
                algo = BooleanRetrieval.GetInstance();
                break;
            default:
                outputTextbox.Text = outputTextbox.Text + "Choose retrieval-algorithm!\r\n";
                return;
        }
        output += algo.BuildIndex("../../DocumentCollection/PilzFuehrer.txt") + "\r\n";

        postIndexMemory = GC.GetTotalMemory(true);

        s = Stopwatch.StartNew();
        output += algo.Start("../../DocumentCollection/PilzFuehrer.txt", new String[] { "Pilz", "blau", "giftig", "Pilze" });
        s.Stop();

        postQueryMemory = GC.GetTotalMemory(true);
        output +=  "\r\nTime elapsed:" + s.ElapsedTicks/(double)Stopwatch.Frequency + "\r\n";

        outputTextbox.Text = output + outputTextbox.Text;
    }

Start(...)の最初の実行は約700µsで実行され、再実行ごとに10µs未満しかかかりません。アプリケーションは、VisualStudio2010とデフォルトの「デバッグ」ビルド構成でコンパイルされます。

プロファイリングやさまざまな実装など、その理由を見つけるために多くの実験を行いましたが、効果は常に同じです。

誰かが私が何をしようとしているのか、あるいは説明さえも私にいくつかの新しいアイデアを私に与えることができれば、私は嬉しいです。

    class BooleanRetrieval:RetrievalAlgorithm
    {
        protected static RetrievalAlgorithm theInstance;

        List<String> documentCollection;
        Dictionary<String, BitArray> index;

        private BooleanRetrieval()
            : base("BooleanRetrieval")
        {

        }

        public override String BuildIndex(string filepath)
        {
            documentCollection = new List<string>();
            index = new Dictionary<string, BitArray>();

            documentCollection.Add(filepath);

            for(int i=0; i<documentCollection.Count; ++i)
            {
                StreamReader input = new StreamReader(documentCollection[i]);

                var text = Regex.Split(input.ReadToEnd(), @"\W+").Distinct().ToArray();

                foreach (String wordToIndex in text)
                {
                    if (!index.ContainsKey(wordToIndex))
                    {
                        index.Add(wordToIndex, new BitArray(documentCollection.Count, false));
                    }

                    index[wordToIndex][i] = true;
                }
            }

            return "Index " + index.Keys.Count + "words.";            
        }

        public override String Start(String filepath, String[] search)
        {
            BitArray tempDecision = new BitArray(documentCollection.Count, true);

            List<String> res = new List<string>();

            foreach(String searchWord in search)
            {

                if (!index.ContainsKey(searchWord))
                    return "No documents found!";

                tempDecision.And(index[searchWord]);
            }


            for (int i = 0; i < tempDecision.Count; ++i )
            {
                if (tempDecision[i] == true)
                {
                    res.Add(documentCollection[i]);
                }
            }

            return res.Count>0 ? res[0]: "Empty!";
        }

        public static RetrievalAlgorithm GetInstance()
        {
            Contract.Ensures(Contract.Result<RetrievalAlgorithm>() != null, "result is null.");
            if (theInstance == null)
                theInstance = new BooleanRetrieval();

            theInstance.Executions++;
            return theInstance;
        }
    }
4

1 に答える 1

1

.Netアプリケーションのコールド/ウォームスタートは、通常、アセンブリをロードするためのJIT時間とディスクアクセス時間の影響を受けます。

多くのディスクIOを実行するアプリケーションの場合、データがメモリキャッシュに収まるほど小さい場合、コンテンツのキャッシュ(アセンブリの読み込みにも適用)が原因で、ディスク上のデータへの最初のアクセスは同じデータの再実行よりもはるかに遅くなります。ディスク用。

  • タスクの最初の実行は、アセンブリとデータのディスクIOに加えて、JIT時間の影響を受けます。
  • アプリケーションを再起動せずに同じタスクを2回実行します。OSのメモリキャッシュからデータを読み取るだけです。
  • アプリケーションの2回目の実行-OSメモリキャッシュとJITからアセンブリを再度読み取ります。
于 2012-06-01T16:41:41.313 に答える