0

前回のスレッドが非常に混乱しており、アイデアも変更されたため、新しいスレッドを投稿しています。私は多くの場所でプログラムを変更しましたが、効率を失うことはありませんでした (少しでも得られました)。今では、以前と同じように単純な整数の配列があり、区切り記号は必要ありません。

参考までに前スレ

この種の質問は、すでに何度も回答されていることを私は知っています。考えられる答えはたくさん見つかりましたが、整数配列を単一の文字列に変換する最速の方法を実装するという私の問題は解決しません。

それでは、

int[] Result = new int[] { 636, 1000234545, 1353678530, 987001 }

私は得るべきです:

636000234545353678530987001

各要素の最後の 9 桁のみを取得していることに注意してください。ホンザ・ブレスタンの修正版は次のとおりです。

StringBuilder sb = new StringBuilder();

for (var i = 0; i < xC; i++)
{
    tempint = Result[i];
    if (tempint > 999999999)
        sb.Append((Result[i]).ToString().Substring(1, 9));
    else
        sb.Append((Result[i]).ToString());
}
return sb.ToString();

そして私の、古い、修正:

//Base – a string array of integers saved as strings {“000”, “001”, … , “999” }
string[] arr = new string[3 * limit];
int x; // temp value

for (int i = 0; i < limit; i++)
{
    x = Result[i];

    if (x > 999999)
    {
        arr [3 * i + 2] = Base [x % 1000];
        arr [3 * i + 1] = Base [x / 1000 % 1000];
        arr [3 * i] = Base [x / 1000000 % 1000];
    }
    else
    {
        if (x < 1000)
        {
            arr [3 * i + 2] = Base [x % 1000];
        }
        else
        {
            arr [3 * i] = Base [x / 1000 % 1000];
            arr [3 * i + 1] = Base [x % 1000];
        }
    }
}
return string.Join(null, arr);

そして速度の違い: Honza: 689 ms My: 331 ms

速度を改善する方法はありますか?多分アセンブラを使用しますか?

4

2 に答える 2

0

OK、私は自分の問題を解決したと信じています;)私がやったことを使いたいと思っている他の人たちのためだけに。ほぼ同じで、最後の部分だけが異なる2つの関数のベンチマークを行う直前に、整数配列を単一の文字列に変換しました。

//Function one:
StringBuilder sb = new StringBuilder();
if (iscarry) sb.Append("1");
xC++;
for (iX = 0; iX < xC; iX++)
{
    tempint = Result[iX];

    if (tempint > 99999)
    {
        sb.Append(SmallBase[tempint / 100000 % 10000]);
        sb.Append(BigBase[tempint % 100000]);
    }
    else
    {
        sb.Append(BigBase[tempint % 100000].TrimStart('0'));
    }
}

return sb.ToString();

//Function two:
xC++;
AnswerArr = new string[2 * xC];
for (iX = 0; iX < xC; iX++)
{
    tempint = Result[iX];

    if (tempint > 99999)
    {
        AnswerArr[2 * iX] = SmallBase[tempint / 100000 % 10000];
        AnswerArr[2 * iX + 1] = BigBase[tempint % 100000];
    }
    else
    {
        AnswerArr[2 * iX] = BigBase[tempint % 100000].TrimStart('0');
    }
}

return string.Join(null, AnswerArr).TrimStart('0');

どちらのコードでも同じ結果が得られます。これは、前の入力の約271ミリ秒です。

整数配列の非常に多くの要素について、StringBuilderは少し速くなると思っていました。そこで、2つのループを作成しました。関数は、文字列として保存された整数を2桁から最大320.000まで加算することになっています。結果は次のとおりです。

with StringBuilder: 5754 ms.
with array & string.Join: 5788 ms.

それは何の意味もありません、これはごくわずかな違いです。だから私はもう一度それを作りました、一緒に最大1.280.000桁。

with StringBuilder: 5242 ms.
with array & string.Join: 5248 ms.

どちらを選ぶかはあなた次第です。文字列ビルダーは理解しやすく、スペースも少なくて済みます。配列を使用する2番目の方法は、より凝ったものです:D

それだけだと思います...これがお役に立てば幸いです。聞いてくれてありがとう。平和!

于 2012-11-19T09:48:01.083 に答える
0

並列処理についてはどうですか、多分それはあなたを助けますか?

    int[] list = new int[100];
    Random rand = new Random();
    for(int k = 0; k < list.Length; k++)
    {
        list[k] = rand.Next(0, 200000);
    }
    object monitor = new object();
    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

    char[] result = new char[list.Length * list.Max().ToString().Length];//worst case scenario.
    for (int j = 0; j < 120000; j++)
    {
        //partitioning.
        Parallel.ForEach(Partitioner.Create(0, list.Length), () => 0.0, (range, state, local) =>
        {
            StringBuilder xc = new StringBuilder();
            for (int i = range.Item1; i < range.Item2; i++)
            {
                //split the number into characters.
                int number = list[i];
                int index = i;
                do
                {
                    int lsd = number % 10;       // Get least significant // digit
                    result[index++] = (char)(lsd + 47);
                    number /= 10;                        // Prepare for next most  // significant digit
                } while(number != 0);
            }
            return 0.0;
        }, local => {});
    }
    stopwatch.Stop(); MessageBox.Show(stopwatch.ElapsedMilliseconds.ToString());

最適化のために、パフォーマンスを向上させる安全でないコードを試してみてください。C#はいくつかのセキュリティチェックを行い、処理が遅くなります。配列インデックスチェックなど。

常に正しいサイズのバッファを割り当て、string.Joinを避けてください。

于 2012-11-18T19:38:44.407 に答える