0

次の形式のハッシュの配列が 2 つあります。

ハッシュ1

[{:root => root_value, :child1 => child1_value, :subchild1 => subchild1_value, bases => hit1,hit2,hit3}...]

ハッシュ2

[{:path => root_value/child1_value/subchild1_value, :hit1_exist => t ,hit2_exist => t,hit3_exist => f}...]

もし私がこれをしたら

Def sample
  results = nil
  project = Project.find(params[:project_id])
  testrun_query = "SELECT root_name, suite_name, case_name, ic_name, executed_platforms FROM testrun_caches WHERE start_date >= '#{params[:start_date]}' AND start_date < '#{params[:end_date]}' AND project_id = #{params[:project_id]} AND result <> 'SKIP' AND result <> 'N/A'"
  if !params[:platform].nil? && params[:platform] != [""]
    #yell_and_log "platform not nil"
    platform_query = nil
    params[:platform].each do |platform|
      if platform_query.nil?
        platform_query = " AND (executed_platforms LIKE '%#{platform.to_s},%'"
      else
        platform_query += " OR executed_platforms LIKE '%#{platform.to_s},%'"
      end
    end
    testrun_query += ")" + platform_query
  end
  if !params[:location].nil? &&!params[:location].empty?
    #yell_and_log "location not nil"
    testrun_query += "AND location LIKE '#{params[:location].to_s}%'"    
  end
  testrun_query += " GROUP BY root_name, suite_name, case_name, ic_name,   executed_platforms ORDER BY root_name, suite_name, case_name, ic_name"
  ic_query = "SELECT ics.path, memberships.pts8210, memberships.sv6, memberships.sv7,   memberships.pts14k, memberships.pts22k, memberships.pts24k, memberships.spb32, memberships.spb64, memberships.sde, projects.name FROM ics INNER JOIN memberships on memberships.ic_id = ics.id INNER JOIN test_groups ON test_groups.id = memberships.test_group_id INNER JOIN projects ON test_groups.project_id = projects.id WHERE deleted = 'false' AND (memberships.pts8210 = true OR memberships.sv6 = true OR memberships.sv7 = true OR memberships.pts14k = true OR memberships.pts22k = true OR memberships.pts24k = true OR memberships.spb32 = true OR memberships.spb64 = true OR memberships.sde = true) AND projects.name = '#{project.name}' GROUP BY path, memberships.pts8210, memberships.sv6, memberships.sv7, memberships.pts14k, memberships.pts22k, memberships.pts24k, memberships.spb32, memberships.spb64, memberships.sde, projects.name ORDER BY ics.path"
  if params[:ic_type] == "never_run"
    runtest = TestrunCache.connection.select_all(testrun_query)
    alltest = TrsIc.connection.select_all(ic_query) 
    (alltest.length).times do |i|
      #exec_pltfrm = test['executed_platforms'].split(",")
      unfinishedtest = comparison(runtest[i],alltest[i])
      yell_and_log("test = #{unfinishedtest}")
      yell_and_log("#{runtest[i]}")
      yell_and_log("#{alltest[i]}")
    end
  end
end

ログに次のように表示されます。

test = true
array of hash 1 = {"root_name"=>"BSDPLATFORM", "suite_name"=>"cli",  "case_name"=>"functional", "ic_name"=>"cli_sanity_test", "executed_platforms"=>"pts22k,pts24k,sv7,"}
array of hash 2 = {"path"=>"BSDPLATFORM/cli/functional/cli_sanity_test", "pts8210"=>"f", "sv6"=>"f", "sv7"=>"t", "pts14k"=>nil, "pts22k"=>"t", "pts24k"=>"t", "spb32"=>nil, "spb64"=>nil, "sde"=>nil, "name"=>"pts_6_20"}
test = false
array of hash 1 = {"root_name"=>"BSDPLATFORM", "suite_name"=>"infrastructure", "case_name"=>"bypass_pts14k_copper", "ic_name"=>"ic_packet_9", "executed_platforms"=>"sv6,"}
array of hash 2 = {"path"=>"BSDPLATFORM/infrastructure/build/copyrights", "pts8210"=>"f", "sv6"=>"t", "sv7"=>"t", "pts14k"=>"f", "pts22k"=>"t", "pts24k"=>"t", "spb32"=>"f", "spb64"=>nil, "sde"=>nil, "name"=>"pts_6_20"}
test = false
array of hash 1 = {"root_name"=>"BSDPLATFORM", "suite_name"=>"infrastructure", "case_name"=>"bypass_pts14k_copper", "ic_name"=>"ic_status_1", "executed_platforms"=>"sv6,"}
array of hash 2 = {"path"=>"BSDPLATFORM/infrastructure/build/ic_1", "pts8210"=>"f", "sv6"=>"t", "sv7"=>"t", "pts14k"=>"f", "pts22k"=>"t", "pts24k"=>"t", "spb32"=>"f", "spb64"=>nil, "sde"=>nil, "name"=>"pts_6_20"}
test = false
array of hash 1 = {"root_name"=>"BSDPLATFORM", "suite_name"=>"infrastructure", "case_name"=>"bypass_pts14k_copper", "ic_name"=>"ic_status_2", "executed_platforms"=>"sv6,"}
array of hash 2 = {"path"=>"BSDPLATFORM/infrastructure/build/ic_files", "pts8210"=>"f", "sv6"=>"t", "sv7"=>"f", "pts14k"=>"f", "pts22k"=>"t", "pts24k"=>"t", "spb32"=>"f", "spb64"=>nil, "sde"=>nil, "name"=>"pts_6_20"}

SO 最初に一致したものだけを取得しますが、残りは異なり、4230 ではなく 1 の結果が得られます

パスとルート/スイート/ケース/ic で照合し、ハッシュ 1 の配列で渡された実行済みプラットフォームと、ハッシュ 2 の配列で true に設定されたプラットフォームを比較する方法が必要です。

4

2 に答える 2

1

これが最速かどうかはわかりませんが、サンプルコードを提供していない元の質問に基づいてこれを書きましたが、

def compare(h1, h2)
  (h2[:path] == "#{h1[:root]}/#{h1[:child1]}/#{h1[:subchild1]}") && \
  (h2[:hit1_exist] == ((h1[:bases][0] == nil) ? 'f' : 't')) && \
  (h2[:hit2_exist] == ((h1[:bases][1] == nil) ? 'f' : 't')) && \
  (h2[:hit3_exist] == ((h1[:bases][2] == nil) ? 'f' : 't'))
end

def compare_arr(h1a, h2a)
  (h1a.length).times do |i|
    compare(h1a[i],h2a[i])
  end
end

テスト:

require "benchmark"

h1a = []
h2a = []

def rstr
  # from http://stackoverflow.com/a/88341/178651
  (0...2).map{65.+(rand(26)).chr}.join
end

def rnil
  rand(2) > 0 ? '' : nil
end

10000.times do
  h1a << {:root => rstr(), :child1 => rstr(), :subchild1 => rstr(), :bases => [rnil,rnil,rnil]}
  h2a << {:path => '#{rstr()}/#{rstr()}/#{rstr()}', :hit1_exist => 't', :hit2_exist => 't', :hit3_exist => 'f'}
end

Benchmark.measure do
  compare_arr(h1a,h2a)
end

結果:

=>   0.020000   0.000000   0.020000 (  0.024039)

私はあなたのコードを見ているので、配列の作成と、ガベージコレクションが必要な配列と文字列を作成している分割と結合を削除することで最適化できると思いますが、これも遅くなりますが、それほどではありませんあなたが言及します。

データベース クエリが遅い可能性があります。それらに対して説明/分析などを実行して、それぞれが遅い理由を確認し、クエリを最適化/削減し、必要に応じてインデックスを追加します。また、CPU とメモリの使用率などを確認します。コードだけではない可能性があります。

ただし、修正する必要がある明確な点がいくつかあります。また、次のような SQL インジェクション攻撃のリスクもいくつかあります。

... start_date >= '#{params[:start_date]}' AND start_date < '#{params[:end_date]}' AND project_id = #{params[:project_id]} ...

パラメータと変数が SQL に直接配置される場所はどこでも危険な場合があります。必ず準備済みステートメントを使用するか、少なくとも SQL で値をエスケープする必要があります。これを最後まで読んでください: http://guides.rubyonrails.org/active_record_querying.html

于 2013-02-05T15:24:10.847 に答える
0
([element_being_tested].each do |el|
  [hash_array_1, hash_array_2].reject do |x, y|
    x[el] == y[el]
  end
end).each {|x, y| puts (x[bases] | y[bases])}

Enumerate the hash elements to test. [element_being_tested].each do |el|

Then iterate through the hash arrays themselves, comparing the given hashes by the elements of the given comparison defined by the outer loop, rejecting those not appropriately equal. (The == may actually need to be != but you can figure that much out)

  [hash_array_1, hash_array_2].reject do |x, y|
    x[el] == y[el]
  end

Finally, you again compare the hashes taking the set union of their elements.

.each {|x, y| puts (x[bases] | y[bases])}

You may need to test the code. It's not meant for production so much as demonstration because I wasn't sure I read your code right. Please post a larger sample of the source including the data structures in question if this answer is unsatisfactory.

Regarding speed: if you're iterating through a large data set and comparing multiple there's probably nothing you can do. Perhaps you can invert the loops I presented and make the hash arrays the outer loop. You're not going to get lightning speed here in Ruby (really any language) if the data structure is large.

于 2013-02-05T01:14:22.017 に答える