1

私たちのプログラムは、各キーが ID を表す記号 (約 10 ~ 20 文字) であるマスター ハッシュを作成します。各値は空のハッシュです。

マスター ハッシュには約 800K のレコードがあります。

それでも、Ruby メモリがほぼ 400MB に達していることがわかります。

これは、各キー/値のペア (シンボル + 空のハッシュ) がそれぞれ約 500B を消費することを示唆しています。

これはルビーにとって正常ですか?

以下のコード:

def load_app_ids
      cols   = get_columns AppFile
      id_col = cols[:application_id]

      each_record AppFile do |r|
        @apps[r[id_col].intern] = {}
      end
end

    # Takes a line, strips the record seperator, and return
    # an array of fields
    def split_line(line)
      line.gsub(RecordSeperator, "").split(FieldSeperator)
    end

    # Run a block on each record in a file, up to 
    # @limit records
    def each_record(filename, &block)
      i = 0

      path = File.join(@dir, filename)
      File.open(path, "r").each_line(RecordSeperator) do |line|
        # Get the line split into columns unless it is
        # a comment
        block.call split_line(line) unless line =~ /^#/

        # This import can take a loooong time.
        print "\r#{i}" if (i+=1) % 1000 == 0
        break if @limit and i >= @limit
      end
      print "\n" if i > 1000
    end

    # Return map of column name symbols to column number
    def get_columns(filename)
      path = File.join(@dir, filename)
      description = split_line(File.open(path, &:readline))

      # Strip the leading comment character
      description[0].gsub!(/^#/, "")

      # Return map of symbol to column number
      Hash[ description.map { |str| [ str.intern, description.index(str) ] } ]
    end
4

1 に答える 1

1

これはRubyでは正常だと思います。各データ構造で使用されるスペースのメトリックはありませんが、一般に、基本的なRubyはこの種の大きな構造ではうまく機能しません。たとえば、キーと値は任意の種類のオブジェクトである可能性があるという事実を考慮に入れる必要があります。これは高水準コーディングには非常に柔軟性がありますが、そのような任意の制御が必要ない場合は非効率的です。

私がirbでこれを行う場合

h = {}
800000.times { |x| h[("test" + x.to_s).to_sym] = {} }

197Mbを使用したプロセスを取得します。

処理中に多数のハッシュ(行ごとに1つ)が作成されたため、プロセスはより多くのスペースを要求しました。Rubyは最終的にクリーンアップしますが、それはすぐには発生せず、メモリもすぐにOSに戻されません。

編集:私はRubyでさまざまな種類の大きなデータ構造を扱ってきたことを追加する必要があります-それらが必要な場合の一般的なアプローチは、コードが制限されたタイプの使用を利用できるネイティブ拡張機能(またはffi)でコード化されたものを見つけることですたとえば、配列。gemnarrayは、数値配列、ベクトル、行列などのこの良い例です。

于 2013-03-19T08:51:23.073 に答える