2

私は、ポインターの配列をループし、各項目についてそのデータを (MySQL データベースまたはフラット ファイルから) 取り込む必要がある PHP 関数を作成しています。何千回もの繰り返しが発生する可能性があるため、これを最適化するアイデアはありますか?

私の最初のアイデアは、私が作業しているキャッシュされたデータの静的な配列を持つことでした。変更すると、そのキャッシュされた配列が変更され、最後にディスクにフラッシュできます。ただし、1000 を超えるアイテムのループでは、配列に約 30 しか保持しない場合、これは役に立ちません。各項目はそれほど大きくありませんが、メモリ内に 1000 個以上あると大きすぎるため、ディスク ストレージが必要になります。

データは、シリアル化されたオブジェクトを gzip 圧縮しただけです。現在、私はデータベースを使用してデータを保存していますが、おそらくフラットファイルの方が高速になると考えています(同時実行の問題は気にせず、解析する必要はなく、解凍してシリアル化を解除するだけです)。一度に 5 つのアイテムを取得して (DB 接続を削減するため)、それらをこのキャッシュに格納するカスタム イテレータが既にあります。しかし繰り返しになりますが、何千回も繰り返す必要がある場合に 30 のキャッシュを使用しても、まったく役に立ちません。

基本的に、これらの多くのアイテムをすばやく反復処理する方法が必要です。

4

4 に答える 4

1

まあ、あなたは先に進むために多くを与えていません。あなたは自分のデータを説明せず、データが何をしているのか、あるオブジェクトが別のオブジェクトとは対照的に必要なとき、それらのオブジェクトが一時的にどのように解放されるのか、どのような状況で元に戻す必要があるのか​​を説明しません.. .

したがって、ここで誰が何を言おうと、完全に闇の中のショットになるでしょう。

…というわけで、これは暗闇でのショットです。

一度に x 個のアイテムしか保持できない場合は、x 個のアイテム用のスペースを確保してください。次に、オブジェクトにアクセスするたびに、時刻をメモします (これは時刻を意味するのではなく、オブジェクトにアクセスする順序を意味する場合があります)。各項目をリストに保持します (リストに実装されていなくても、ヒープのような構造として実装されている場合があります)。これにより、最近使用された項目がリスト内でより早く表示されます。新しいものをメモリに入れる必要がある場合は、最も長く使用されていたものを置き換えてから、その項目をリストの先頭に移動します。アイテムが必要なときにリスト内の正確な場所を把握できるように、アイテムの別のインデックスを保持する必要がある場合があります。次に行うことは、アイテムが配置されている場所を検索し、その親ポインターと子ポインターを適切にリンクしてから、リストの先頭に移動することです。

これはLRUアルゴリズムと呼ばれます。仮想メモリのページ置換方式です。ボトルネック (ディスク I/O) を、おそらく回避できなくなるまで遅らせます。このアルゴリズムは最適な置換を保証するものではありませんが、それでも十分に機能することに注意してください。

それを超えて、(可能であれば) コードを大幅に並列化することをお勧めします。これにより、1 つの項目をロードまたはダンプするためにハード ディスクにアクセスする必要がある場合に、そのプロセッサを実際の作業でビジー状態に保つことができます。

< 編集 > あなたのコメントに基づいて、あなたはニューラル ネットワークに取り組んでいます。データの最初のフィード (修正段階の前) の場合、またはそれを積極的に分類に使用している場合、アルゴリズムに適合する方法がない限り、アルゴリズムがどのように悪い考えであるかはわかりません。メモリ内で最も一般的に使用されるノード。

修正段階 (おそらくバックプロップ?) では、どのノードをメモリに保持する必要があるかが明らかになるはずです...なぜなら、それらのノードにはすでにアクセスしているからです!

ネットワークが大規模な場合、ディスク I/O なしではうまくいきません。秘訣は、それを最小限に抑える方法を見つけることです。< /編集 >

于 2009-12-17T01:39:41.967 に答える
0

明らかに、それをメモリに保持することは何よりも高速です。各商品の大きさは?1個1Kでも1万個で10Mです。

于 2009-12-17T01:26:03.367 に答える
0

必要なデータを取得した後は、いつでもループから抜け出すことができます。ループし続けないようにします。保存しているのがフラットファイルの場合..サーバーのHDDは、ファイルサイズが異なる数千または数百万のファイルを含むことになります。ただし、DBに格納されている実際のファイル全体について話している場合。それをフォルダーに保存し、そのファイルのパスをDBに保存する方がはるかに優れています。そして、プルされたアイテムを XML に入れてみてください。これにより、アクセスがはるかに簡単になり、プルされたアイテムの詳細 (名前、アップロード日など) の多くの属性を含めることができます。

于 2009-12-17T01:26:28.873 に答える
0

オブジェクトが最初に読み取られるときに memcached を使用してオブジェクトを保存し、その後の呼び出しでキャッシュされたバージョンを使用できます。Memcached は RAM を使用してオブジェクトを保存するため、十分なメモリがある限り、大幅な高速化が実現します。memcached への php API があります

于 2009-12-17T01:43:00.650 に答える