2

ActiveRecord システムを備えた PHP フレームワークを使用しています。大量のメモリを使用し、大きな結果を伴う複雑なクエリの実行時間が長い ActiveRecord ですぐに問題が発生しました。

私のリファレンス ページ (10,000 個のオブジェクトを含む配列を生成するスクリプト) では、メモリ消費量を 100 MB 以上から最大 15 MB に削減し、実行時間を 5 秒以上から最大 1.5 秒に短縮しました。

これら 2 つの測定値だけを考慮する必要がありますか?それとも、PHP を介して利用できる他のメトリックを調べる必要がありますか?

オブジェクト変数に物を格納する関数をその場で計算するように変更することで、ほとんどの改善を達成しました。したがって、ローカルホストでテストしてもCPU不足がないため、CPUが心配です...ただし、ライブ環境では、他のリクエストなどのためにCPUが常に使用されます。しかし、PHPでCPU消費を測定するにはどうすればよいですか?

例: アクティブなレコードがインスタンス化されるたびに、フィールド、ルール、および関係が各オブジェクト インスタンス内のプライベート プロパティに設定されます。これを関数に変更し、オブジェクト プロパティを使用する代わりに、常にコンパイルして値を返します。

記憶に任せましょう:

class Record {
  private $relations;
  private $fields;
  function __construct() {
    $this->setRelations();
    $this->setFields();
  }
  private function setRelations() {
    // This process of getting predefined relations, checking for correct data,
    // and some other calculations is done once, on every construct.
    // The result is stored in $this->relations;
    // This costs memory!
  }
  private function setFields() {
    // This process of getting predefined fields, checking for correct data,
    // and some other calculations is done once, on every construct.
    // The result is stored in $this->fields;
    // This costs memory!
  }
  private function getRelations() {
    // This is fast. Loading the set relations from memory.
    return $this->relations;
  }
  private function getFields() {
    // This is fast. Loading the set relations from memory.
    return $this->fields;
  }
}

CPUに任せましょう:

class Record {
  function __construct() {
    // Drop the setter methods. Let the CPU work when using the getters.
  }
  private function getRelations() {
    // This process of getting predefined relations, checking for correct data,
    // and some other calculations is done once, on every getFields()
    // This costs CPU!
    return $relations;
  }
  private function getFields() {
    // This process of getting predefined fields, checking for correct data,
    // and some other calculations is done once, on every getFields()
    // This costs CPU!
    return $fields;
  }
}

私の2つの主な質問は次のとおりです。

  1. 何が良いですか?
  2. CPU 消費量を測定するにはどうすればよいですか?
4

2 に答える 2

1

おそらく、CPU が実行している他のことや、プロセスがブロックされているかどうかによって影響を受ける実時間として実行時間を測定しています。たとえば、データベース呼び出しを行うと、CPU がアイドル状態の間もウォール クロックが動作し続けます。このアイドル時間は、忙しいように見えても、他のリクエストを処理するために使用できます。

XHProfなどのプロファイラーを使用して、アプリケーション全体のメモリ、CPU、ウォール クロックのコストを正確に測定します。これは、関数が呼び出す他の関数を含めて、および除外して、各関数の所要時間と消費メモリを測定し、アプリケーションにドリルダウンできるようにします。

時間とメモリのどちらが重要かは、アプリケーション プロファイル全体に依存します。大量のメモリを必要とするリクエストが多数ある場合は、より多くの CPU を使用するように新しいリクエストを調整する必要があります。逆も同様です。さらに、より多くのリクエストを同時に処理しようとすると、短時間に多くのメモリを使用することがより重要になります。

于 2012-08-10T20:19:41.050 に答える
1

ここで 1 つの非常に重要な要素を忘れていました: データベースです。適切に索引付けされていることを確認してください。クエリ プロファイリングを実行して、最悪のシナリオで検査される行数を確認します。10 回中 9 回は DB であり、パフォーマンスの問題を引き起こすコードではありません。

于 2012-08-10T20:17:41.653 に答える