3

私はこのデータを持っています:

members = {"total"=>3, "data"=>[
  {"email"=>"foo@example.org", "timestamp"=>"2013-03-16 01:11:01"},
  {"email"=>"bar@example.org", "timestamp"=>"2013-03-16 02:07:30"},
  {"email"=>"exx@example.org", "timestamp"=>"2013-03-16 03:06:24"}
]}

そして、次のような配列を生成したい:

["foo@example.org", "bar@example.org", "exx@example.org"]

現在私は使用しています:

members['data'].collect { |h| h['email'] }
  1. パフォーマンスに関してそれを達成するためのより効率的な方法はありますか?
  2. それを達成するためのさらに短い方法はありますか?

Rails を利用できます。

4

3 に答える 3

4

他の回答に加えて、たとえば、値を収集するときに利益を得ることができるため、Hash使用symbolsを構築できる場合は追加します。keysperformance

require 'benchmark'

members_without_sym = {"total"=>3, "data"=>[
  {"email"=>"foo@example.org", "timestamp"=>"2013-03-16 01:11:01"},
  {"email"=>"bar@example.org", "timestamp"=>"2013-03-16 02:07:30"},
  {"email"=>"exx@example.org", "timestamp"=>"2013-03-16 03:06:24"}
]}

members_with_sym = {:total=>3, :data=>[
  {:email=> "foo@example.org", :timestamp => "2013-03-16 01:11:01"},
  {:email=> "bar@example.org", :timestamp => "2013-03-16 02:07:30"},
  {:email=> "exx@example.org", :timestamp=> "2013-03-16 03:06:24"}
]}

Benchmark.bm(1) do |algo|
  algo.report("Without symbol"){
    2_000_000.times do 
       members_without_sym['data'].collect { |h| h['email'] }
    end   
  }
  algo.report("With symbol"){
    2_000_000.times do 
      members_with_sym[:data].collect { |h| h[:email] }      
    end
  }
end

結果:

        user     system      total        real
Without symbol  2.260000   0.000000   2.260000 (  2.254277)
With symbol  0.880000   0.000000   0.880000 (  0.878603)
于 2013-03-16T14:15:00.783 に答える
3

部品をネイティブ拡張に最適化する以外h['email']に、上記の例をより効率的にする方法がわかりません。そうすることによる効率の向上は、サンプルのデータセットのサイズではわずかであり、そもそもこのデータのフェッチ/解析の I/O を最適化するよりもはるかに少ないと思います。

データ ソースによっては、文字列ではなくラベルとしてハッシュ キーを使用することが一般的な Ruby のイディオムであり、メモリ使用の点でもより効率的です。これにより効率が大幅に向上する可能性があり、データを変換するために多大な労力を費やす必要がない場合 (たとえば、データ ソースから与えられたデータ構造の性質を何らかの方法で変更することができます。一度クエリを実行するためだけにハッシュを変換する必要はありません!)

于 2013-03-16T13:57:20.250 に答える
2
members = {"total"=>3, "data"=>[
  {"email"=>"foo@example.org", "timestamp"=>"2013-03-16 01:11:01"},
  {"email"=>"bar@example.org", "timestamp"=>"2013-03-16 02:07:30"},
  {"email"=>"exx@example.org", "timestamp"=>"2013-03-16 03:06:24"}
]}

temp = members["data"].map{|x|x["email"]}

["foo@example.org", "bar@example.org", "exx@example.org"] を与える

Rubyでのマップと収集の違いは?

--

たぶん構造体はパフォーマンスを向上させるでしょう

Record = Struct.new(:email, :timestamp)
members = {"total"=>3, "data"=>[
  Record.new("foo@example.org","2013-03-16 01:11:01"),
  Record.new("bar@example.org","2013-03-16 02:07:30"),
  Record.new("exx@example.org","2013-03-16 03:06:24")
]}

temp = members["data"].map(&:email)

http://blog.rubybestpractices.com/posts/rklemme/017-Struct.html

于 2013-03-16T14:02:11.623 に答える