3

私の同僚は、小さなコンサルタント会社のすべての従業員の毎週 (日曜日から土曜日まで) の進歩を表示するレポートに取り組んでいます。対象の週の日に対応する列を表示する、彼が書いたコードがあります。彼のアルゴリズムは次のとおりです。

  1. 月の最初の日が何曜日であるかを取得します。日曜日の場合は、フラグをゼロに設定します。それ以外の場合は、1 に設定します。
  2. 月のすべての日を繰り返します。日曜日の場合、フラグをインクリメントします。次に、フラグの値が表示される週と等しい場合、現在の日に対応する列を表示します。それ以外の場合は、列を非表示にします。

もちろん、フラグは現在の週が何であるかを示します。

別のアルゴリズムを提案しました:

  1. 指定された週の最初 (F) と最後の (L) 日が月のどの日であるかを取得します。たとえば、2009 年 10 月の第 1 週は、1 日の火曜日に始まり、3 日の土曜日に終わります。
  2. 1 日目から F-1 日目に対応する列を反復処理し、それらを非表示にします。
  3. 日 F から L に対応する列を反復して表示します。
  4. 日 L+1 から DaysOfMonth に対応する列を繰り返し処理し、それらを非表示にします。

私のアルゴリズムの「難しい」部分はパート 1 です。それを行うアルゴリズムの複雑さは一定であるため、「理解しにくい」のように「難しい」という意味です。そして、私のアルゴリズムには、よりタイトなループを持つという利点があります。私のピアのループは、毎月の比較を行います。私はしません。

これはほんの一例であり、ここで過度に最適化するのは少し偏執的すぎると言うかもしれません。しかし、パフォーマンスが重要な実際のコードを書くとき、彼のプログラミング スタイルは少しも変わりません。

彼のコードには、次のテストも含まれています。

/* doSomething() doesn't change the state of the relevant variables. */
if (condition)
{
    flag++;
    if (flag > test)
        doSomething();
}
else
    if (flag >= test)
        doSomething();

もちろん、次のように実行できる場合:

if (flag >= test);
    doSomething();
if (condition)
    flag++;

私は何をしますか?!?!?!

編集: コード サンプルの比較を修正しました。

4

8 に答える 8

10

ご友人の考えは正しいと思います。説明するのに 1 時間かかるが、特定のパフォーマンス目標を念頭に置いていないアルゴリズムよりも、明らかに正しいアルゴリズムを取り上げてください。

「コードはマシン X で 200 マイクロ秒以内に今後 10 年間のすべての月について正しい結果を提供できる必要がある」などの特定のパフォーマンス要件があり、単純なコードが要件を満たさない場合は、バージョン。

(あなたが投稿したコードサンプルは、複雑さが少ないため、確かに明らかに優れています。)

于 2009-10-31T13:58:56.420 に答える
5

あなたの説明から、私があなたの同僚に反対するかどうかはわかりません。ここでの重要な問題は、このコードがパフォーマンスのボトルネックになるかどうかです。

あなたのアルゴリズムに切り替えるようにを説得するには、問題のアプリケーションをプロファイリングし、このコードがパフォーマンスにとって重要であることを示す必要があります。次に、変更を加えてプロファイルを再度作成します。そうすれば、比較のための客観的な根拠が得られます。

2 つのアルゴリズムに意味のある違いがある場合は、切り替える価値があるかどうかを 2 人で話し合うことができます。

Web アプリケーションのページ読み込み時間が心配な場合は、ハイ パフォーマンス Web サイトYahoo パフォーマンス ガイドラインの教訓を思い出してください。サーバ。

測定なしの最適化を主張することは、単純なアルゴリズムのパフォーマンスへの影響を無視するのと同じくらい危険です。

于 2009-10-31T13:59:09.177 に答える
4

明らかにあなたが間違っているので、干渉しないでください... 2つのコードは同等ではありません。条件=1、フラグ=0、テスト=1を取るだけです

于 2009-10-31T14:05:36.470 に答える
3

こんばんは

実際の利益をもたらさない巧妙で過度に複雑なアルゴリズムよりも、制約内で実行されるアルゴリズムの単純さを優先することをお勧めします。私の経験では、この種の過度に巧妙なトリックは、将来のメンテナンスの悪夢になる可能性が高いです!

この考えは、次の引用によってよりよく表現されます。

「有能なプログラマーは、自分の頭蓋骨のサイズが厳密に制限されていることを十分に認識しています。したがって、彼は完全に謙虚にプログラミング作業に取り組み、とりわけペストのような巧妙なトリックを回避します。」- Edsger Dijkstra による 1972 年の ACM Turing Lecture " The Humble Programmer "

ところで、その論文は素晴らしい読み物です!EWDijkstra アーカイブでオンラインで入手できる彼の他の多くの論文とともに

HTH

乾杯、

于 2009-10-31T14:13:17.633 に答える
3

これはあなたの仕事ですか、それとも彼の仕事ですか? 彼の場合は、彼にやらせてください。私は効率を重視するタイプですが、実際、何かが非効率的で自分の手に負えないものに見えると、非常にイライラします。

SO には 200 人を優に超える人々がいて、私の最も「効率的な」アイデア、アルゴリズム、およびコードを恥ずかしく思うことができます。おそらくそれ以上、担当者だけでは行けません。Linus Torvalds 自身がサインアップした場合、彼は私たちと同じように 1 から始めます。

あなたが考慮しなければならないことは、人々が書いたコードを維持できる必要があるということです。つまり、彼らはそれを自分が産んだかのように理解しなければなりません。誰かが私のアルゴリズムよりもはるかに効率的な別のアルゴリズムを示したとしても、私はそれに慣れていない限り、そのアルゴリズムを使用しません。

これが共同プロジェクトである場合は、自分のやり方で書き、スピードアップを示してから、同僚が本当に理解できるように非常に辛抱強い時間を同僚と過ごしてください。

あなたが 5 年前に書いたものを振り返ってみてください。誰もが実際にやって学ぶ必要があり、誰もが自分のペースで、特に学習を行っています。

于 2009-10-31T14:02:10.050 に答える
2

ここに問題があるとは思いません...彼のバージョンには目標に到達するための少し回り道がありますが、彼はそこに到達します.

私が言おうとしているこの声明は、文脈から切り離されるべきではありません: しかし、そのようにそれを行う人は常に存在します - そしてそれは間違っていません.何かをしますが、彼の方法がどれほど醜くても、結果を得る方法を知っています。
何かの正しいアルゴリズムを誰も知らない場合、それは本当の命の恩人になる可能性があります...おそらく彼は何とかそれをダックテープします.

于 2009-10-31T14:10:51.460 に答える
2

私はここで一般的な意見に同意します: パフォーマンスの改善によってコードが非常に読みにくくなるのであれば、その変更を行う正当な理由があるべきです。

とはいえ、最初に頭に浮かんだことでいつも落ち着くべきだという意味ではありません。場合によっては、同等またはほぼ可読性のある、明白に優れた代替案が存在することがあります。

アルゴリズムの選択を真剣に受け止めるよう同僚を説得したい場合は、慎重に戦いを選ぶ必要があります。彼の世界をひっくり返して、見つけたすべてのケースに問題を押し付けようとしないでください. 明らかに優れた明確な代替アルゴリズムを思い付くことができる場合にのみ、提案を行うことから始め、彼が抵抗した場合は撤回する準備をしてください。

あなたがよそよそしいと感じている場合は、彼にヒントを与えたり、誘導的な質問をしたり、彼が自分でそれを理解するのを助けるために考えられる他のテクニックを考えたりすることさえできます.

于 2009-10-31T14:28:59.230 に答える
1

あなたの痛みが分かります。プログラマーは本質的に頑固です。誰もがプログラムを構築するための独自の原則とルールを持っています。他の意見がその一部と衝突する場合、プログラマーの意見を変えることは、超高層ビルの基礎の柱を動かすようなものです。:)

于 2009-10-31T17:25:21.027 に答える