2

大規模なデータ セット (250,000 X 1,000 double のデータ キューブ、約 4 ギガバイトのファイル) があり、Python で記述した以前の OOP クラスのセットを使用して操作したいと考えています。現在、データセットはすでに非常に大きいため、マシンのメモリに読み込むには、少なくとも半分に分割する必要があるため、計算のオーバーヘッドが懸念されます。私の OOP クラスは、データを処理するために新しいオブジェクトを作成します (この場合、250,000 個の新しいオブジェクトが必要です。各オブジェクトは 1,000 個の double の配列です)。ジェネリック OOP 言語のオブジェクトを作成する際に必要なメモリとコンピューティングのオーバーヘッドはどれくらいですか? パイソンで?C++ ではどうでしょうか。

はい、配列である新しいクラスを作成できることに気付きました。しかし、1) これらのクラスはすでに完成しており、2) 後でアクセスできるように、作成した各オブジェクトを配列に戻します。質問は教育的です

*更新: 時間、自分の時間、およびコンピューターを効率的に使用したいと考えています。必要がなければ、既に持っているプログラムを書き直したくありません。また、コードの最適化に時間を費やすことは私の時間を無駄にします。コンピューターの時間を無駄にしても、それほど気にしません。私は実際に 4Gig RAM の 64 ビット マシンを持っています。データは画像であり、各ピクセルでいくつかのフィルターを実行する必要があります。*

4

14 に答える 14

3

http://code.activestate.com/recipes/546530/を参照してください

これは、Pythonオブジェクトのおおよそのサイズです。

OOサイズの「ペナルティ」は、多くの場合、(a)処理を簡素化し、(b)そもそもメモリに保持するものを少なくする機能によって相殺されます。

OOパフォーマンスのオーバーヘッドはありません。零。C ++では、クラス定義は存在しないように最適化され、残っているのはCだけです。Pythonでは、すべての動的言語と同様に、動的プログラミング環境で実行時ルックアップが追加されます。ほとんどの場合、これらは辞書への直接ハッシュです。コンパイラがすべての解決を行ったコードよりも低速です。ただし、それでも非常に高速で、オーバーヘッドは比較的低くなっています。

Cの悪いアルゴリズムは、Pythonの正しいアルゴリズムよりも簡単に遅くなる可能性があります。

于 2008-12-16T20:48:12.727 に答える
3

手続き型/関数型プログラミング言語でも同様の問題が発生します。大量のデータをどのようにメモリに格納しますか? 構造体または配列も機能しません。

この規模のデータを管理するには、特別な手順を実行する必要があります。

ところで: オブジェクト指向言語を選択するかどうかの理由としてこれを使用することはありません。

于 2008-12-16T20:24:58.250 に答える
3

少し OT: Flyweightデザイン パターンは、大規模なデータセットを操作するときにオーバーヘッドを最小限に抑えるのに役立ちます。あなたの問題の詳細を知らなければ、それがどれほど当てはまるかわかりませんが、一見の価値があります...

于 2008-12-16T21:15:02.250 に答える
2

あなたの設計の欠点をOOPのせいにするのは公平だとは思いません。他のプログラミング プラットフォームと同様に、OO は適切な設計にも最適でない設計にも使用できます。これがプログラミング モデル自体の障害になることはめったにありません。

しかし、あなたの質問に答えるために: 250000 個の新しいオブジェクトを割り当てるには、私が認識しているすべての OO 言語でいくらかのオーバーヘッドが必要になるため、同じインスタンスを介してデータをストリーミングすることを回避できれば、おそらくより良いでしょう。

于 2008-12-16T20:10:28.700 に答える
1

実際の C++ OO メモリ オーバーヘッドは、仮想メソッドを持つオブジェクトごとに 1 つのポインター (場合によっては 4 ~ 8 バイト) です。ただし、他の回答で述べたように、動的割り当てによるデフォルトのメモリ割り当てオーバーヘッドは、これよりも大幅に大きくなる可能性があります。

中途半端に物事を合理的に行っている場合、どちらのオーバーヘッドも 1000*8 バイトの double 配列と比較して重要ではない可能性があります。実際に割り当てのオーバーヘッドが心配な場合は、独自のアロケータを作成できますが、最初に、それによって実際に大幅な改善が得られるかどうかを確認してください。

于 2008-12-16T21:24:38.957 に答える
0

他のポスターが述べているように。オブジェクトがプロセスにかなりのオーバーヘッドを与えるとは思わない。オブジェクトへのポインタを格納する必要がありますが、残りの「double」はプログラムのメモリの99%を使用します。

このデータをはるかに小さなサブセットに分割できますか?あなたが達成しようとしているタスクは何ですか?メモリ内のすべてのデータが何のために必要なのかを知りたいと思います。おそらく、それをシリアル化するか、haskellで遅延評価のようなものを使用することができます。

問題のドメインをよりよく理解できるように、フォローアップを投稿してください。

于 2008-12-16T20:43:57.273 に答える
0

データの形状とデータを格納するように設計した構造を知らずに答えることは不可能です。

于 2008-12-16T20:06:48.753 に答える
0

「オーバーヘッド」は、選択したプラットフォームと実装に大きく依存します。

数GBのファイルから何百万ものデータを読み取る際にメモリの問題が発生した場合、オブジェクトのメモリ消費が最大の懸念事項ではないというアルゴリズムの問​​題を抱えていることになります。データを保存します。

于 2008-12-16T20:34:36.920 に答える
0

問題は、OO からのオーバーヘッドではないと思います。

C++ を OO 言語として受け入れ、C++ コンパイラが C のプリプロセッサであることを思い出すと (少なくとも、私が C++ を使用していたときはそうでした)、C++ で行われることはすべて C で行われます。C にはオーバーヘッドがほとんどありません。したがって、ライブラリに依存します。

オーバーヘッドは、解釈、マネージド実行、またはメモリ管理から生じると思います。ツールとノウハウを持っている人にとっては、C++ と Python のどちらが最も効率的かを簡単に見つけることができます。

C++ が回避可能なオーバーヘッドをどこに追加するかはわかりません。私はPythonについてあまり知りません。

于 2008-12-16T20:48:41.353 に答える
0

「操作」を定義してください。4ギガのデータを本当に操作したいのなら、なぜすぐにすべてをメモリに引っ張って操作したいのですか?

とにかく、4ギガのRAMが必要なのは誰ですか?:)

于 2008-12-16T21:09:31.123 に答える
0

これほど大きなデータセットを定期的に操作しなければならない場合、バケツロードの RAM を備えた64 ビットマシンを入手できますか? さまざまな理由から、リソースを大量に消費するソフトウェア (この場合は SQL Server Analysis Services) を使用していることに気付きました。この種の古い 64 ビット マシンは、大量の RAM を使用し、最先端ではありませんが依然としてかなり高速な CPU を備えています。

中古の HP ワークステーションをいくつか入手し、高速 SCSI ディスクをいくつか取り付けました。2007 年半ばには、4 GB または 8 GB の RAM と 5 台の 10K または 15K SCSI ディスクを備えたこれらのマシンの購入価格は、1,500 ~ 2,000 ポンドでした。ディスクはマシンの半分のコストであり、I/O パフォーマンスは必要ない可能性があるため、おそらくそれほど多くを費やす必要はありません。 私が購入した種類の XW9300は、ebay でかなり安く購入できるようになりました。この投稿では、 ebay を使用してハイスペックな 64 ビット ボックスを安く入手するためのさまざまなオプションについて説明します。これらのマシンの 16 GB または 32 GB へのメモリ アップグレードは、パーツの定価のごくわずかな金額で eBay から入手できます。

于 2008-12-16T21:28:39.120 に答える
0

私の友人は MIT の教授で、ある学生が彼に、画像解析プログラムの実行速度が遅い理由を尋ねました。それはどのように建てられましたか?すべてのピクセルはオブジェクトであり、隣接するピクセルにメッセージを送信します!

私があなたなら、使い捨てプログラムで試してみます。私の疑いでは、クラスが非常に慎重にコーディングされていない限り、オブジェクトの割り当て、初期化、および割り当て解除に多くの時間を費やしていることがわかり、ブライアンが言ったように、セットを介してデータをスプールできる可能性があります再利用されたオブジェクトの。

編集:すみません。オブジェクトを再利用していると言ったので、それは良いことです。いずれにせよ、それを実行したら、それをプロファイリングするか、(あなたが私の場合) コール スタックを数回ランダムに読み取るだけで、時間がどこに行くかについての質問に答えることができます。

于 2008-12-16T21:29:24.093 に答える
0

データ セットのサイズと比較すると、250K オブジェクトのオーバーヘッドは無視できます。

あなたは間違った道を進んでいると思います; オブジェクトのせいにしないでください;-)

于 2008-12-16T21:03:58.450 に答える
0

データを半分に分割して操作できるので、各レコードを個別に操作していると思いますか? 一度に 1 つのレコードを読み取って操作し、結果を保存するには、デシリアライザーを変更する必要があるように思えます。

基本的に、char を返す Peek() を実行する文字列パーサー クラスが必要です。空白などをスキップする方法を知っています。データ形式を理解するクラスをラップすると、オブジェクトを吐き出すことができるはずです。ファイルを読み取る時間。

于 2008-12-16T21:37:35.670 に答える