apeescape2.com
  • メイン
  • トレンド
  • リモートの台頭
  • ライフスタイル
  • プロセスとツール
プロジェクト管理

コードの最適化:最適化するための最適な方法

パフォーマンスの最適化は、コードに対する最大の脅威の1つです。

あなたは考えているかもしれません、 別のものではありません それら 人 。わかります。語源から判断すると、あらゆる種類の最適化は明らかに良いことであるはずなので、当然、あなたはそれを上手にしたいと思っています。

より良い開発者として群衆から離れるだけではありません。することを避けるだけではありません 「ダン」 デイリーWTF 、しかし、コードの最適化が正しいことだと信じているからです。あなたは自分の仕事に誇りを持っています。



コンピュータハードウェアはどんどん速くなり、そして ソフトウェア 作るのは簡単ですが、あなたがどんな簡単なことでも できるようになりたいだけだ、くそー 常に最後よりも時間がかかります。あなたはこの現象(ちなみに、ヴィルトの法則として知られています)に頭を振って、その傾向に逆らうことを決意します。

それはあなたの高貴ですが、やめてください。

やめて!

プログラミングの経験がどれほどあっても、自分の目標を妨げるという重大な危険にさらされています。

どうして?バックアップしましょう。

まず第一に、何 です コードの最適化?

多くの場合、それを定義するとき、コードが 実行する より良い。コードの最適化とは、プログラムが可能な限り少ないメモリまたはディスクスペースを使用するように、CPU時間またはネットワーク帯域幅を最小限に抑えるように、または追加のコアを最大限に活用するように、コードの書き込みまたは書き換えであると言います。

実際には、デフォルトで別の定義、つまりコードの記述を減らすこともあります。

しかし、その目標を持って書いている先制的に悪いコードは、誰かの側でとげになる可能性がさらに高くなります。誰?あなたのコードを理解しなければならない次の不運な人、それはあなた自身かもしれません。そして、あなたのような賢くて有能な人は、自己破壊を避けることができます。間違いなく直感的であるように見えるにもかかわらず、あなたの目的を高貴に保ちながら、あなたの手段を再評価してください。

コードゴルフ:+ 197%、パフォーマンス:-398%、シンプルさ:-9999%

したがって、コードの最適化は少し漠然とした用語です。それは、コードを最適化できる他の方法のいくつかを検討する前です。これについては以下で説明します。

一緒に探検しながら、賢人のアドバイスを聞くことから始めましょう ジャクソン の有名なコード最適化ルール:

  1. しないでください。
  2. (専門家のみ!) しないでください まだ 。

1.やらないでください:完璧主義のチャネリング

まず、かなり恥ずかしいほど極端な例から始めます。昔、SQLの素晴らしい、ケーキを食べて食べ過ぎた世界に足を踏み入れていたときからです。問題は、それから私がケーキを踏んで、それが濡れていて足のようなにおいがし始めたので、もう食べたくなかったということでした。

私はちょうどSQLの素晴らしい、食べ過ぎの世界に足を踏み入れていました。問題は、それから私はケーキを踏んだ…

待つ。私が今作って説明した比喩のこの自動車事故から戻ってみましょう。

私はイントラネットアプリの研究開発を行っていましたが、いつか私が働いていた中小企業の完全に統合された管理システムになることを望んでいました。それは彼らのためにすべてを追跡し、彼らの当時のシステムとは異なり、他の開発者が使用した不安定な自家製のフラットファイルのものではなく、RDBMSによってバックアップされるため、データを失うことはありません。白紙の状態だったので、最初からすべてをできるだけスマートにデザインしたかったのです。このシステムのアイデアは私の頭の中で花火のように爆発し、私はテーブルの設計を開始しました。CRM、会計モジュール、在庫、購入、CMS、およびプロジェクト管理のための連絡先とその多くのコンテキストバリエーションです。

それがすべて停止すること、開発- そして パフォーマンス面では、…ご想像のとおり、最適化のためです。

オブジェクト(テーブルの行として表される)は、現実の世界では互いに多くの異なる関係を持つ可能性があり、これらの関係を追跡することでメリットが得られることがわかりました。より多くの情報を保持し、最終的にはあらゆる場所でビジネス分析を自動化できます。これをエンジニアリングの問題と見なして、システムの柔軟性を最適化したように見えることを行いました。

この時点で、あなたの顔に注意することが重要です。あなたの手のひらが顔を傷つけた場合、私は責任を負いません。準備はいいですか? 2つのテーブルを作成しました:relationship 1つは、relationship_typeへの外部キー参照を持っていました。 relationshipデータベース全体の任意の2行を参照し、それらの間の関係の性質を説明できます。

データベーステーブル:employee、company、relationship、relationship_type

ちょっと、あなた。その柔軟性を最適化したばかりです とてもくそー 。

実際、多すぎます。今、私は新しい問題を抱えていました:与えられたrelationship_type当然、行のすべての組み合わせの間で意味がありません。 personは理にかなっているかもしれませんがemployed byがありましたcompanyとの関係。これは、たとえば2つのdocument間の関係と意味的に同等になることはありません。

OK、問題ありません。 relationship_typeに2つの列を追加して、この関係を適用できるテーブルを指定します。 (これらの2つの列をrelationship_type.idを参照する新しいテーブルに移動することでこれを正規化することを考えたと思われる場合は、ここでボーナスポイントが得られます。 たぶん......だろう テーブルの複数のペアに意味的に適用すると、テーブル名が重複することはありません。結局のところ、テーブル名を変更する必要があり、該当するすべての行でテーブル名を更新するのを忘れた場合、バグが発生する可能性があります。振り返ってみると、少なくともバグは私の頭蓋骨に生息するクモに餌を提供していたでしょう。)

データベーステーブル:relationship_typeとapplicable_to、およびrelationship_typeの複雑なデータ

ありがたいことに、私はこの道を行き過ぎてしまう前に、手がかりの嵐で意識を失いました。目が覚めたとき、RDBMSの内部外部キー関連のテーブルをそれ自体の上に多かれ少なかれ再実装できたことに気づきました。通常、私は「私はとてもメタだ」という大げさな宣言をすることで終わる瞬間を楽しんでいますが、残念ながら、これはそれらの1つではありませんでした。忘れる スケーリングに失敗する —この設計の恐ろしい肥大化により、私のまだシンプルなアプリのバックエンドが作成されました。このアプリのDBにはまだテストデータがほとんど入力されておらず、ほとんど使用できませんでした。

Luke、外部キーを使用してください。

少し戻って、ここで使用されている多くの指標のうちの2つを見てみましょう。 1つは柔軟性です。これは私の目標でした。この場合、本質的にアーキテクチャである私の最適化は時期尚早ではありませんでした。

コード最適化の手順:アーキテクチャは、最適化するプログラムの最初の部分です

(最近公開された記事で詳しく説明しますが、 時期尚早の最適化の呪いを回避する方法 。)それにもかかわらず、私の解決策は遠く離れていることによって見事に失敗しました あまりにも フレキシブル。もう1つの指標であるスケーラビリティは、私がまだ検討していなかったものの、なんとか破壊したものでした。 少なくとも見事に 巻き添え被害を伴う。

そうです、「ああ」

ダブルフェイスパーム、1つのフェイスパームが

これは、最適化が完全にうまくいかない可能性があることについての私にとって強力な教訓でした。私の完璧主義は完全に崩壊しました。私の賢さは、私がこれまでに作った中で最も客観的に賢くない解決策の1つを生み出すように私を導きました。

コードではなく、習慣を最適化する

プロトタイプとテストスイートが機能してその正しさを証明する前にリファクタリングする傾向があることに気付いたら、この衝動を他にどこに向けることができるかを検討してください。数独とメンサは素晴らしいですが、実際にプロジェクトに直接利益をもたらすものの方が良いかもしれません。

  1. セキュリティ
  2. 実行時の安定性
  3. 明快さとスタイル
  4. コーディング効率
  5. テストの有効性
  6. プロファイリング
  7. ツールキット/ DE
  8. DRY(Do n’t Repeat Yourself)

ただし、注意してください。これらの特定の1つを最適化すると、他の人が犠牲になります。少なくとも、時間はかかります。

ここで、コードの作成にどれだけの芸術があるかを簡単に確認できます。上記のいずれについても、間違った選択であると考えられたものが多すぎるか少なすぎるかについての話をすることができます。ここで誰が考えているのかも、文脈の重要な部分です。

たとえば、DRYについて:ある仕事で、少なくとも80%冗長なステートメントであるコードベースを継承しました。これは、その作成者が関数をいつどのように作成するかを知らなかったためです。コードの他の20%は、紛らわしいほど自己相似でした。

私はそれにいくつかの機能を追加することを任されました。そのような機能の1つは、実装するすべてのコードで繰り返す必要があり、将来のコードは慎重に行う必要があります。 コピーパスタ 新機能を利用する。

明らかに、それは私自身の正気(高い価値)と将来の開発者のためだけにリファクタリングする必要がありました。しかし、私はコードベースを初めて使用したため、最初にテストを作成して、リファクタリングによってリグレッションが発生しないことを確認しました。実際、彼らはまさにそれを実行しました。スクリプトが生成したすべてのgobbledygook出力の中で、気付かなかった2つのバグを途中で見つけました。

結局、私はかなりうまくやったと思いました。リファクタリング後、数行の単純なコードで難しい機能と見なされていたものを実装したことで上司に感銘を与えました。さらに、コードは全体的に桁違いにパフォーマンスが向上しました。しかし、同じ上司が私に遅すぎたと言って、プロジェクトはすでに終了しているはずだと言ったのは、この後それほど長くはありませんでした。翻訳:コーディング効率がより優先されました。

注意:特定の[側面]から一体を最適化すると、他の人が犠牲になります。少なくとも、時間はかかります。

当時上司がコードの最適化を直接評価していなかったとしても、私はそこで正しいコースを受講したと思います。リファクタリングとテストがなければ、実際に正しくなるまでにもっと時間がかかったと思います。つまり、コーディング速度に焦点を合わせると、実際にはそれが妨げられたでしょう。 (ねえ、それが私たちのテーマです!)

これを、私の小さなサイドプロジェクトで行ったいくつかの作業と比較してください。プロジェクトでは、新しいテンプレートエンジンを試していましたが、新しいテンプレートエンジンを試すことはプロジェクトの最終目標ではありませんでしたが、最初から良い習慣を身に付けたいと思っていました。

追加したいくつかのブロックが互いに非常に類似していることに気付くとすぐに、さらに、各ブロックは同じ変数を3回参照する必要があり、DRYベルが頭の中で鳴り、正しいものを見つけようとしました。このテンプレートエンジンでやろうとしていたことを行う方法。

数時間の無駄なデバッグの後、これは現在、私が想像した方法でテンプレートエンジンでは不可能であることが判明しました。なかっただけでなく 完璧 ドライソリューション;ありませんでした どれか ドライソリューション!

私のこの1つの値を最適化しようとして、コーディングの効率と幸福を完全に狂わせました。これは、この迂回によって、その日のプロジェクトの進捗が失われたためです。

それでも、私は完全に間違っていましたか?特に新しい技術コンテキストでは、ベストプラクティスを後でではなく早く知るために、少し投資する価値がある場合があります。書き直すコードが少なくなり、元に戻す習慣が悪くなりますよね?

いいえ、以前の逸話での私の態度とはまったく対照的に、コードの繰り返しを減らす方法を探すのは賢明ではなかったと思います。その理由は、コンテキストがすべてであるということです。私は、長距離に落ち着くのではなく、小さな遊びのプロジェクトで新しいテクノロジーを模索していました。いくつかの余分な行と繰り返しは誰も傷つけませんでしたが、焦点の喪失は私と私のプロジェクトを傷つけました。

待って、ベストプラクティスを探すのは悪い習慣になる可能性がありますか?時々。もし私の メイン 目標は、新しいエンジンを学ぶこと、または一般的に学ぶことでした。それなら、いじくり回し、限界を見つけ、研究を通じて無関係な機能や落とし穴を発見するのに十分な時間が費やされたでしょう。しかし、これが私の主な目標ではないことを忘れていたので、コストがかかりました。

私が言ったように、それは芸術です。そして その芸術の発展 リマインダーのメリット、 しないでください 。少なくとも、作業中にどの値が機能しているか、どの値が最も重要であるかを検討することができます。 君は に 君の 環境。

その2番目のルールはどうですか? いつ 実際に最適化できますか?

2.やらないで まだ :誰かがすでにこれを行っています

OK、あなた自身であろうと他の誰かであろうと、あなたはあなたのアーキテクチャがすでに設定されていて、データフローが考えられて文書化されていることに気づき、そしてコーディングする時が来ました。

取りましょう まだやらないで さらに一歩: まだコーディングしないでください 。

これ自体は時期尚早の最適化のように聞こえるかもしれませんが、重要な例外です。どうして?恐ろしいNIHS、または「ここで発明されていない」症候群を回避するため。優先順位にコードのパフォーマンスと開発時間の最小化が含まれていると仮定します。そうでない場合、目標が完全に学習指向である場合は、この次のセクションをスキップできます。

可能性はありますが 四角いホイールを再発明する 純粋な傲慢さから、あなたや私のような正直で謙虚な人々は、私たちが利用できるすべてのオプションを知らないだけでこの間違いを犯すことができると私は信じています。スタック内のすべてのAPIとツールのすべてのオプションを理解し、それらが成長および進化するときにそれらを常に把握することは、確かに多くの作業です。

しかし、この時間を置くことはあなたを専門家にし、あなたがCodeSODの無数の人物であり、日時計算機や文字列マニピュレーターの魅力的なテイクによって残された荒廃の痕跡のために呪われたり嘲笑されたりするのを防ぎます。

(この一般的なパターンに対する適切な対抗策は、古いJava Calendar APIですが、 修正されました 。)

標準ライブラリを確認し、フレームワークのエコシステムを確認し、問題をすでに解決しているFOSSを確認します

おそらく、あなたが扱っている概念にはかなり標準的でよく知られている名前があるので、インターネットですばやく検索すると、時間を大幅に節約できます。

例として、私は最近、ボードゲームのAI戦略の分析を行う準備をしていました。ある朝、私が覚えている特定の組み合わせ論の概念を使用するだけで、計画していた分析を桁違いに効率的に実行できることに気づきました。現時点では、この概念のアルゴリズムを自分で理解することに興味がなかったので、検索する正しい名前を知っていたので、すでに先を行っていました。しかし、約50分間の調査と予備的なコードの試行の後、見つけた半完成の擬似コードを正しい実装に変えることができなかったことがわかりました。 (著者が誤ったアルゴリズム出力を想定し、その想定に一致するようにアルゴリズムを誤って実装し、コメント提供者がこれを指摘し、その後数年経ってもまだ修正されていないというブログ投稿があると信じられますか?)その時点で、私の朝のお茶キックインし、[name of concept] [my programming language]を検索しました。 30秒後、GitHubからコードを修正し、実際にやりたいことを実行していました。自分で実装する必要があると想定するのではなく、具体的に言語を含めるだけで、すべてが意味しました。

データ構造を設計し、アルゴリズムを実装する時が来ました

…繰り返しますが、プレイしないでください ゴルフコード 。実際のプロジェクトでは、正確さと明確さを優先します。

時間の投資:10時間、実行時間:+ 25%、メモリ使用量:+ 3%、混乱:100%

さて、あなたは見てきましたが、ツールチェーンに組み込まれている、またはWeb上で自由にライセンスされている問題を解決するものはまだありません。あなたはあなた自身を展開します。

問題ない。アドバイスは次の順序で簡単です。

  1. 初心者プログラマーに簡単に説明できるように設計してください。
  2. その設計によって生成された期待に適合するテストを作成します。
  3. 初心者プログラマーがコードからデザインを簡単に収集できるように、コードを記述します。

単純ですが、おそらく従うのは難しいでしょう。これはコーディングの習慣と コードの臭い とアートと クラフト エレガンスが作用します。この時点で行っていることには明らかに工学的な側面がありますが、繰り返しになりますが、プレイしないでください ゴルフコード 。実際のプロジェクトでは、正確さと明確さを優先します。

あなたがビデオが好きなら、 上記の手順を実行している人の1人です 、 多かれ少なかれ。ビデオを嫌う人のために、要約します。これは、Googleの就職の面接でのアルゴリズムコーディングテストです。インタビュー対象者は、最初に、伝達しやすい方法でアルゴリズムを設計します。コードを書く前に、実際の設計で期待される出力の例があります。次に、コードは自然に続きます。

テスト自体に関しては、一部のサークルでは、テスト駆動開発が論争になる可能性があることを私は知っています。その理由の一部は、それがやり過ぎであり、開発時間を犠牲にするまで宗教的に追求される可能性があるためだと思います。 (繰り返しになりますが、最初から1つの変数でも最適化しすぎて、足を踏み入れてしまいます。) ケントベックでさえ、TDDをそれほど極端なものにしません 、そして彼はエクストリームプログラミングを発明し、TDDに関する本を書きました。したがって、出力が正しいことを確認するために、簡単なことから始めてください。結局のところ、とにかくコーディングした後、手動でそれを行うでしょう? (ロックスタープログラマーで、最初にコードを記述した後でコードを実行することすらできない場合は、お詫びします。その場合は、コードの将来のメンテナーにテストを任せることを検討してください。 彼ら すばらしい実装を壊すことはありません。)したがって、手動で視覚的な差分を行う代わりに、テストを実施して、すでにコンピュータにその作業を任せています。

アルゴリズムとデータ構造を実装するかなり機械的なプロセスでは、行ごとの最適化を行わないでください。 考える この時点で、カスタムの低水準言語extern(Cでコーディングしている場合はアセンブリ、Perlでコーディングしている場合はCなど)を使用します。理由は単純です。アルゴリズムが完全に置き換えられ、プロセスの後半までそれが必要かどうかがわからない場合、低レベルの最適化の取り組みは最終的には効果がありません。

ECMAScriptの例

オン 優れたコミュニティコードレビューサイトexercism.io 、最近見つけた エクササイズ これは、重複排除または明確化のために最適化を試みることを明示的に提案しました。重複排除を最適化したのは、前述のように、DRY(前述のように有益なコーディングの考え方)を使いすぎた場合に、いかにばかげたことが起こるかを示すためです。私のコードは次のようになりました。

const zeroPhrase = 'No more'; const wallPhrase = ' on the wall'; const standardizeNumber = number => { if (number === 0) { return zeroPhrase; } return '' + number; } const bottlePhrase = number => { const possibleS = (number === 1) ? '' : 's'; return standardizeNumber(number) + ' bottle' + possibleS + ' of beer'; } export default class Beer { static verse(number) { const nextNumber = (number === 0) ? 99 : (number - 1); const thisBottlePhrase = bottlePhrase(number); const nextBottlePhrase = bottlePhrase(nextNumber); let phrase = thisBottlePhrase + wallPhrase + ', ' + thisBottlePhrase.toLowerCase() + '. '; if (number === 0) { phrase += 'Go to the store and buy some more'; } else { const bottleReference = (number === 1) ? 'it' : 'one'; phrase += 'Take ' + bottleReference + ' down and pass it around'; } return phrase + ', ' + nextBottlePhrase.toLowerCase() + wallPhrase + '. '; } static sing(start = 99, end = 0) { return Array.from(Array(start - end + 1).keys()).map(offset => { return this.verse(start - offset); }).join(' '); } }

そこに文字列の重複はほとんどありません!このように書くことで、ビールの歌にテキスト圧縮の形式を手動で実装しました(ただし のみ ビールの歌のために)。正確には、どのようなメリットがありましたか?さて、あなたがボトルの代わりに缶からビールを飲むことについて歌いたいとしましょう。私はこれを変えることで達成できました 1つのインスタンス のbottle canへ。

いいね!

…正しい?

いいえ、すべてのテストが失敗するためです。わかりました。簡単に修正できます。検索してbottleに置き換えます。ユニットテスト仕様で。そして、それはそもそもコード自体にそれを行うのとまったく同じくらい簡単であり、意図せずに物事を壊すという同じリスクを伴います。

その間、私の変数は、bottlePhraseのような奇妙な名前が付けられます。何の関係もありません ボトル まったく。これを回避する唯一の方法は、行われる変更の種類を正確に予測し、vesselなどのより一般的な用語を使用することです。またはcontainer bottleの代わりに私の変数名で。

このように将来を保証するという知恵はかなり疑わしいものです。 何かを変えたいと思う確率はどれくらいですか? そして、あなたがそうするならば、あなたが変えるものはとても便利にうまくいくでしょうか? bottlePhraseでたとえば、次のような言語にローカライズする場合はどうなりますか 2つ以上の複数形があります ?そうです、時間をリファクタリングすると、コードは後でさらに悪化する可能性があります。

しかし、あなたの要件が 行う 変化し、あなたはそれらを予測しようとしているだけではありません、 その後 多分それはリファクタリングする時です。または、それでも延期することができます。現実的に、いくつの船の種類またはローカリゼーションを追加しますか?とにかく、重複排除と明確さのバランスをとる必要がある場合は、一見の価値があります カトリーナオーウェンによるこのデモンストレーション 。

私自身の醜い例に戻りましょう。言うまでもなく、重複排除のメリットはここではそれほど実現されていません。その間、いくらかかりましたか?

そもそも書き込みに時間がかかることを除けば、読み取り、デバッグ、および保守が非常に簡単になりました。適度な量の複製が許可されている読みやすさのレベルを想像してみてください。例えば、 4つの詩のバリエーションのそれぞれを綴る 。

しかし、まだ最適化されていません。

アルゴリズムが実装され、その出力が正しいことが証明されたので、おめでとうございます。ベースラインがあります!

最後に、最適化する時が来ましたね。いいえ、まだ まだやらないで 。ベースラインを取り、良いことをする時が来ました 基準 。これに関する期待のしきい値を設定し、テストスイートに貼り付けます。次に、何かが突然このコードを遅くした場合、たとえそれがまだ機能していても、ドアから出る前にわかります。

関連するユーザーエクスペリエンスの全体が実装されるまで、最適化を保留します。その時点までは、必要とはまったく異なるコードの部分をターゲットにしている可能性があります。

アプリ(またはコンポーネント)をまだ完成させていない場合は、完成させます。アルゴリズムのベンチマークベースラインをすべて設定します。

これが完了したら、システムの最も一般的な実際の使用シナリオをカバーするエンドツーエンドのテストを作成してベンチマークする絶好の機会です。

たぶん、すべてがうまくいくことがわかるでしょう。

あるいは、実際の状況では、何かが遅すぎるか、メモリを大量に消費していると判断したかもしれません。

OK、 今 あなたは最適化することができます

それについて客観的になる唯一の方法があります。勃発する時が来ました 炎のグラフ およびその他のプロファイリングツール。経験豊富なエンジニアは、初心者よりもよく推測する場合としない場合がありますが、それは重要ではありません。確実に知る唯一の方法は、プロファイルを作成することです。これは、パフォーマンスのためにコードを最適化するプロセスで常に最初に行うことです。

特定のエンドツーエンドテスト中にプロファイルを作成して、実際に最大の影響を与えるものを取得できます。 (後で、展開後、使用パターンを監視することは、システムのどの側面が将来測定するのに最も関連性があるかを把握するための優れた方法です。)

デザインの原則をリストする

プロファイラーを完全に使用しようとしているのではないことに注意してください。この時点での目標は、見つけることだけであるため、通常、ステートメントレベルのプロファイリングよりも関数レベルのプロファイリングを探しています。 どのアルゴリズム ボトルネックです。

プロファイリングを使用してシステムのボトルネックを特定したので、実際に最適化を試みることができ、最適化を行う価値があると確信できます。また、途中で行ったベースラインベンチマークのおかげで、試行がどれほど効果的(または非効果的)であったかを証明することもできます。

全体的なテクニック

まず、可能な限り高レベルを維持することを忘れないでください。

知ってますか?究極のユニバーサル最適化トリックは、すべての場合に適用されます。

-描画するものを減らします
-更新するものが少ない

--Lars Doucet(@larsiusprime) 2017年3月30日

アルゴリズム全体のレベルでは、1つの手法は次のとおりです。 強度低下 。ただし、ループを数式に減らす場合は、コメントを残すことに注意してください。誰もがすべての組み合わせ論の公式を知っている、または覚えているわけではありません。また、数学の使用には注意してください。最終的には、強度低下と思われることがそうではない場合があります。たとえば、x * (y + z)としましょう。明確なアルゴリズムの意味があります。何らかの理由で、ある時点で脳が同類項のグループ化を自動的に解除するように訓練されている場合は、それをx * y + x * zとして書き直したくなるかもしれません。一つには、これは読者とそこにあった明確なアルゴリズムの意味との間に障壁を置きます。 (さらに悪いことに、今は実際に もっと少なく 追加の乗算演算が必要なため、効率的です。ズボンをはいたループ展開のようなものです。)いずれにせよ、意図についての簡単なメモは大いに役立ち、コミットする前に自分のエラーを確認するのに役立つ場合もあります。

数式を使用している場合でも、ループベースのアルゴリズムを別のループベースのアルゴリズムに置き換える場合でも、違いを測定する準備ができています。

ただし、データ構造を変更するだけでパフォーマンスが向上する可能性があります。使用している構造で実行する必要のあるさまざまな操作のパフォーマンスの違い、およびその他の方法について学習します。ハッシュはコンテキスト内で機能するのが少し面倒に見えるかもしれませんが、配列よりも優れた検索時間はそれだけの価値がありますか?これらは、決定するのはあなた次第のトレードオフのタイプです。

これは、コンビニエンス関数を呼び出すときに、どのアルゴリズムが実行されているかを知ることになることに気付くかもしれません。つまり、最終的には強度低下と同じです。また、ベンダーのライブラリが舞台裏で何をしているのかを知ることは、パフォーマンスだけでなく重要です。 意図しないバグを回避するためにも 。

マイクロ最適化

OK、システムの機能は完了しましたが、UXの観点からは、パフォーマンスをもう少し微調整することができます。あなたがより高くできるすべてをしたと仮定して、それはする時間です 検討する これまでずっと避けてきた最適化。このレベルの最適化は、明快さと保守性とのトレードオフであるため、検討してください。しかし、今がその時だと決めたので、ステートメントレベルのプロファイリングを進めてください。これで、実際に重要なシステム全体のコンテキストに入ることができます。

使用するライブラリと同様に、コンパイラまたはインタプリタのレベルで、数え切れないほどのエンジニアリング時間が費やされています。 (結局のところ、コンパイラの最適化とコード生成は 独自の巨大なトピック )。これも真実です プロセッサレベルで 。せずにコードを最適化しようとしています 最低レベルで何が起こっているかを認識している 四輪駆動であるということは、あなたの車もより簡単に停止できるということを意味すると考えるようなものです。

それ以上の一般的なアドバイスを提供するのは難しいです。なぜなら、それは実際には技術スタックとプロファイラーが指しているものに依存するからです。しかし、あなたは測定しているので、解決策が問題の文脈から有機的かつ直感的に提示されない場合は、すでに助けを求めるのに最適な立場にあります。 (睡眠と他のことを考えるのに費やした時間も役立ちます。)

この時点で、コンテキストとスケーリング要件に応じて、JeffAtwoodはおそらく ハードウェアを追加するだけ 、開発者の時間よりも安くなる可能性があります。

多分あなたはそのルートに行かないでしょう。その場合、さまざまなカテゴリの調査に役立つ可能性があります コードの最適化 テクニック:

  • キャッシング
  • ビットハック そして 64ビット環境に固有のもの
  • ループの最適化
  • メモリ階層の最適化

すなわち:

  • CおよびC ++でのコード最適化のヒント
  • Javaでのコード最適化のヒント
  • .NETでのCPU使用率の最適化
  • ASP.NETWebファームのキャッシュ
  • SQLデータベースのチューニング または 特にMicrosoftSQLServerのチューニング
  • Scalaのプレイをスケーリングする!フレームワーク
  • 高度なWordPressパフォーマンスの最適化
  • JavaScriptプロトタイプとスコープチェーンによるコードの最適化
  • Reactパフォーマンスの最適化
  • iOSアニメーションの効率
  • Androidのパフォーマンスのヒント

とにかく、私は 行う もう少し持っている してはいけない あなたのために:

複数の異なる目的で変数を再利用しないでください。 保守性という点では、これはオイルなしで車を走らせるようなものです。これは、最も極端な埋め込み状況でのみ意味があり、そのような場合でも、もはや意味がないと私は主張します。これは、整理するコンパイラの仕事です。自分で実行してから、コードを1行移動すると、バグが発生します。メモリを節約するという幻想はあなたにとってそれだけの価値がありますか?

理由を知らずにマクロやインライン関数を使用しないでください。 はい、関数呼び出しのオーバーヘッドはコストです。ただし、これを回避すると、コードのデバッグが困難になることが多く、実際には遅くなることもあります。たまに良いアイデアであるという理由だけで、このテクニックをどこでも使用することは、 ゴールデンハンマー 。

ループを手動で展開しないでください。 繰り返しますが、この形式の ループの最適化 ほとんどの場合、より良いものです コンパイルなどの自動化されたプロセスによって最適化 、コードの可読性を犠牲にすることではありません。

最後の2つのコード最適化の例の皮肉なことに、実際にはパフォーマンスが低下する可能性があります。もちろん、ベンチマークを行っているので、特定のコードについてそれを証明または反証することができます。ただし、パフォーマンスが向上した場合でも、アート側に戻って、読みやすさと保守性を損なうだけの価値があるかどうかを確認してください。

それはあなた次第です:最適化された最適化

パフォーマンスの最適化を試みることは有益です。しかし、多くの場合、それは非常に時期尚早に行われ、多くの悪い副作用を伴い、最も皮肉なことに、パフォーマンスの低下につながります。最適化の芸術と科学、そして最も重要なこととして、その適切なコンテキストに対する理解が深まったことを願っています。

これにより、最初から完璧なコードを書くという概念を捨てて、代わりに正しいコードを書くことができれば幸いです。トップダウンで最適化し、ボトルネックがどこにあるかを証明し、それらを修正する前後に測定することを忘れないでください。これが、最適化を最適化するための最適で最適な戦略です。幸運を祈ります。

基本を理解する

ソフトウェアの最適化とはどういう意味ですか?

ソフトウェアの最適化とは、柔軟性、保守性、パフォーマンスなど、ソフトウェアの多くの側面を指します。ただし、通常はパフォーマンスが暗示されます。

パフォーマンスの最適化とは何ですか?

パフォーマンスの最適化でさえ、コードのさまざまな側面を参照できます。ディスク上のサイズとCPU時間のように、側面が本質的に互いに対立する場合もあります。実行時間を最小限に抑えることが最も一般的な目標です。

ループ最適化とは何ですか?

ループ最適化とは、出力を変更せずにパフォーマンスを向上させる方法でループを変換することです。多くの変換は保守性と可読性を犠牲にして行われるため、多くの場合、これはコンパイラーに任せるのが最善です。

パフォーマンスを時期尚早に最適化すると、通常、何がリスクにさらされますか?

正確性、明快さ、保守性、柔軟性、そして皮肉なことに、最適化されている特定の側面(メモリ使用量、応答時間など)さえも。さらに皮肉なことに、最初から最適化しても、最適化されているコードが組み込み関数またはサードパーティ関数に置き換えられても、最終的には時間を節約できません。

コードを書く前にとられるコード最適化のステップは何ですか?

最初にアーキテクチャを最適化し、次に(自分で実装する場合でも)アルゴリズムとデータ構造を最適化します。

専門家でさえ従う必要のある既存のコードで使用されるコード最適化手順は何ですか?

まず、プロファイル。専門家でさえ、最適化が必要なものを誤って特定することがよくあります。その後、適切な手順は基礎科学です。変更を加える前後に、慎重に検討されたベンチマークを取ります。正しいコンテキストと測定がなければ、最適化は暗闇の中でのショットです...良い友達でいっぱいの部屋で!

より良いWebポータルの設計:最初の基本

Uxデザイン

より良いWebポータルの設計:最初の基本
3Dグラフィックス:WebGLチュートリアル

3Dグラフィックス:WebGLチュートリアル

技術

人気の投稿
通年続く予算を立てる方法
通年続く予算を立てる方法
SnapchatのIPO:ARPU、ダミーがすべて
SnapchatのIPO:ARPU、ダミーがすべて
意欲的なGoogleGlass開発者向けのチュートリアル:最初のGlassアプリの構築
意欲的なGoogleGlass開発者向けのチュートリアル:最初のGlassアプリの構築
npmのガイド:Node.jsパッケージマネージャー
npmのガイド:Node.jsパッケージマネージャー
単一責任の原則:優れたコードのレシピ
単一責任の原則:優れたコードのレシピ
 
効果的な初期展開パイプラインを構築する方法
効果的な初期展開パイプラインを構築する方法
著名なeコマースのトレンドとそのデザインへの影響(インフォグラフィック付き)
著名なeコマースのトレンドとそのデザインへの影響(インフォグラフィック付き)
オンデマンド製品開発:デジタルトランスフォーメーションの推進
オンデマンド製品開発:デジタルトランスフォーメーションの推進
Twitterデータマイニング:Pythonを使用したビッグデータ分析のガイド
Twitterデータマイニング:Pythonを使用したビッグデータ分析のガイド
PhalconPHP:高負荷のRESTfulAPIのソリューション
PhalconPHP:高負荷のRESTfulAPIのソリューション
人気の投稿
  • CFOは毎日何をしていますか
  • c法人またはs法人
  • 検索は機能ではありません
  • 不況の影響を最も受けている業界
  • 英国の銀行および金融サービス会社
カテゴリー
革新 デザイナーライフ 収益と成長 Uxデザイン 収益性と効率性 設計プロセス トレンド エンジニアリング管理 ライフスタイル モバイル

© 2021 | 全著作権所有

apeescape2.com