11

コード (C#/WPF) のパフォーマンスが非常に重要な部分を使用しており、可能な限り迅速に 2 つの System.TimeSpan 値の間でモジュラス演算を実行する必要があります。

このコードは 1 秒間に何千回も実行されるため、手動のループ計算を使用することは絶対に避けたいと考えています。

2 つの TimeSpans 間のモジュラスの考え方は少し奇妙に思えるかもしれません。説明させてください -
TimeSpan
A = 1 分 30 秒
TimeSpan B = 20 秒 があるとします。

一般的な操作とその妥当な結果のリストを次に示します。

A + B = (TimeSpan)1 分 50 秒

A - B = (TimeSpan)1 分 10 秒

A * B = 合理的な計算方法がないTimeSpan に整数を掛ける
ことができるはずです。A * 5 = (TimeSpan) 7 分 30 秒
Microsoft は、TimeSpan と整数の間の乗算を実装していません。

A / B = (int)4 または (double)4.5
この操作は .NET フレームワークに直接実装されていませんが、完全に理にかなっています。
A には 4.5 個の B があります (4.5 * 20 = 90)。

A % B = (TimeSpan) 10 Seconds
適切な TimeSpan 除算が与えられた場合、TimeSpan モジュラスは非常に単純なはずです。
A / Bは実際には (int)4残り(TimeSpan)10 秒に等しい。商と剰余は異なるデータ型です。これが、Microsoft がこれを直接実装していない理由かもしれません。

ループせずにこれを計算する効率的な方法を見つける必要があります。通常、私は短いループに反対しませんが、これらの TimeSpans は大きく異なる可能性があります。TimeSpans 間の指数関数的な差が大きいほど、商は大きくなります。商が大きいほど、「除算ループ」を実行する必要がある反復回数が多くなります。これは、アプリのこの部分では許可できない依存関係です。

SOには何かアイデアがありますか?

4

5 に答える 5

27

乗算は簡単です:

TimeSpan a5 = TimeSpan.FromTicks(A.Ticks * 5);

同様に A/B:

double aOverB = (double)A.Ticks / B.Ticks;

そして A%B:

TimeSpan aModB = TimeSpan.FromTicks(A.Ticks % B.Ticks);

デモンストレーション:

using System;

class Test
{
    static void Main()
    {
        TimeSpan a = TimeSpan.FromSeconds(90);
        TimeSpan b = TimeSpan.FromSeconds(20);

        TimeSpan a5 = TimeSpan.FromTicks(a.Ticks * 5);
        double aOverB = (double)a.Ticks / b.Ticks;
        TimeSpan aModB = TimeSpan.FromTicks(a.Ticks % b.Ticks);

        Console.WriteLine(a5);
        Console.WriteLine(aOverB);
        Console.WriteLine(aModB);
    }
}

出力:

00:07:30
4.5
00:00:10
于 2009-08-18T18:51:14.197 に答える
6

のようなものでしょうか

new TimeSpan( A.Ticks % B.Ticks))

あなたが望む結果を与えますか?ティックはその作業を行うのに適切な単位でしょうか? スパンを秒またはミリ秒などに変換する必要があるかもしれません。これに対するあなたのアプリケーションが何であるかわかりません。

于 2009-08-18T18:50:35.413 に答える
4

時間範囲からそれが表す秒数に変換できる場合は、それらの値を変更してから元に戻すことができます。

于 2009-08-18T18:49:37.633 に答える
3

timespan オブジェクトでこれを直接行うのではなく、ティック機能を使用します。

このようなもの。

TimeSpan oSpan = new TimeSpan(0, 1, 20, 0, 0);
TimeSpan oShort = new TimeSpan(0, 0, 20, 0, 0);
long modRemainder = oSpan.Ticks % oShort.Ticks;
TimeSpan oRemainderSpan = new TimeSpan(modRemainder);

1 つのステップに要約できますが、説明のためにこれを行いました。これにより、必要な数学的操作を簡単に行うことができます。

于 2009-08-18T18:52:59.340 に答える
1

私が考えることができる最善の方法は、TotalSeconds プロパティを使用してそれをモジュロすることです。ただし、これらは Double であり、小数の値を許可するため、求めている正確な値に到達しない場合があります。いつでも全体の部分を取得してモジュロすることができますが、速度が心配なので、1秒間に数百回実行する必要がある操作には遅すぎるかもしれません。

于 2009-08-18T18:55:55.607 に答える