14

線形進行情報を使用して操作 (IE: ファイルのダウンロード) の ETA を計算する最良の方法を探しています。

呼び出される次のメソッドがあるとしましょう。

void ReportProgress(double position, double total)
{
    ...
}

私にはいくつかのアイデアがあります:

  • 一定時間 (過去 10 秒など) の進行状況を計算し、その速度を操作の平均速度として使用します。
  • 報告された最後の x 個の進行状況のセットを保持し、各増分の速度を計算し、平均を使用します。
4

8 に答える 8

8

どちらも開発者として以前に私を噛んだことがあるので、私は実際には両方のアイデアを軽蔑しています。

1つ目は、実際に操作が速くなる状況を考慮しておらず、あと10分とのことで、3分後に戻ってきて終了します。

2つ目は、操作が遅くなることを考慮していません-Windowsエクスプローラーはこの方法を使用する必要があると思います。ファイルの90%をコピーする時間の90%が常にかかり、最後の10をコピーする時間の90%がかかるためです。ファイルの%:-)。

私は長い間、これらの両方の数値を計算して平均化することに取り組んできました。クライアントは気にしません(彼らは他の2つのオプションも気にしませんでした、彼らはただいくつかの進歩を見たいだけです)、しかしそれは私を気分を良くします、そしてそれは本当に私が一日の終わりに気にするすべてです;- )。

于 2009-05-12T13:18:36.540 に答える
7

このような何かがトリックを行う必要があります:

void ReportProgress(double position, double total)
{
    static TimeType startTime;

    if (position == 0)
    {
        startTime = GetTime();
        return; // to avoid a divide-by-zero error
    }

    TimeType elapsedTime = GetTime() - startTime;
    TimeType estimatedRemaining = elapsedTime * total / position;
    TimeType estimatedEndTime = GetTime() + estimatedRemaining;

    // Print the results here
}

進捗状況が100%に近づくにつれて、見積もりは真実に近づきます

于 2009-05-12T13:16:10.043 に答える
5

この問題はほとんど解決できないと思いますが、実行中のプロセスについてもう少し知識があれば、正確な見積もりを作成することは可能です。また、未知数が多い場合は、それらの未知数をユーザーに知らせて、ユーザーがそれらを考慮できるようにすることをお勧めします。

ファイルのバッチをダウンロードする簡単な例を挙げると、2 つの既知の変数があります。

  • ファイル数
  • ファイルのサイズ

ファイルごとに一定のオーバーヘッドがあります (接続を確立するのにかかる時間と、ファイル システム上のファイルを開くのにかかる時間)。ファイルのサイズに関連する明らかなダウンロード時間もあります。これを現在のダウンロード速度の残り時間として表現できる関数を作成するのは簡単で、ダウンロード速度があまり変動しない限り正確です。しかし、そこに問題があります。

実行中の操作の正確なモデルがあれば、外部からの影響がなければ、操作にかかる時間を簡単に予測できます。そして、それが可能なことはめったにありません。

ただし、これらの外部の影響を理解し、説明しようとするソリューションを求めることはできます。ユーザーは、新しい ETA に合わせて計画を調整できるため、速度が劇的に変化したときにアラートを受け取ると役立つ場合があります。現在の操作に影響を与えている要因を説明することも役立つ場合があります。例えば

Your download will complete in 6 minutes, if the download speed stays at 50k/s

これにより、速度が変化する可能性が高いことがわかっている場合、ユーザーは知識に基づいた推測を行うことができます。そして最終的にはフラストレーションの減少につながります。

于 2009-05-12T14:29:04.090 に答える
1

「進行状況バー」ではなく ETA が必要な場合は、複数の数値を指定できますか?

一定期間の平均ダウンロード速度を計算し (ダウンロード全体がどれくらい続く可能性があるかにもよりますが、10 分以上かかる場合は 5 秒ごとで問題ありません)、平均を記録します。

次に、上限と下限の見積もりの​​ 2 つの数値を指定できます。

平均がダウンロードの合計時間の適切な指標になると確信している場合は、40 パーセンタイルと 60 パーセンタイルを表示できます。平均ダウンロード時間が大幅に異なる場合は、10 パーセンタイルと 90 パーセンタイルの方がよい可能性があります。

29 分 35.2 秒と言われて何マイルも離れていて、更新ごとに大きく変化するよりも、「21 ~ 30 分」という球場を見たいと思います。

于 2009-05-12T14:02:57.307 に答える
0

動作タイミングの整合性によります。一貫している場合は、以前の操作の平均時間を使用するのが完全に合理的です。そうでない場合は、現在の操作のタイミングを調整して外挿することをお勧めします。

編集:操作が以前の実行と一貫性がなく、最初から最後まで一貫性がない場合は、解決できない問題があります。予測不可能なことを予測することは常に楽しいです:)

過小評価するか過大評価するかを事前に決定し、見積もりにファッジファクターを追加することができます。たとえば、過大評価したい場合、最初の10%に6秒かかる場合は、60秒に外挿してから、1.5を掛けて、合計で90秒の見積もりを取得できます。完了率が高くなるにつれて、100%で1.0になるまでファッジファクターを減らします。

于 2009-05-12T13:15:06.893 に答える
0

私は、長くて時間のかかる計算の ETA を必要とするプロジェクトに取り組みましたが、結局、プロセスを同じサイズのバッチに分割することになりました。次に、各バッチの計算にかかる時間を計り、かかった時間が過去の計算時間の FIFO リストに追加されます。

次に、リスト内の時間が平均化され、結果の時間に残りのバッチ数が乗算されます。

number of batches = N
size of batch = x
past computations length = l (t0,t1,...,tl)
avg time per batch = (t0 + t1 + ... + tl) / l = t
computed batches = n

ETA = t * (N - n)

リストは固定長であり、推定プロセスが「記憶」し、計算の可能なピークに適応できるように十分な長さにする必要がありますが、計算速度の変化に迅速に適応できるように十分に短くする必要があります (例:競合するタスクの終了 / より多くの帯域幅)

于 2018-12-05T14:55:52.883 に答える