簡體   English   中英

紅寶石:如何有效地迭代哈希中的元素

[英]ruby: how to iterate elements in a hash efficiently

我有一個很大的哈希,我想對其進行迭代。 Hash.each似乎太慢了。 有什么有效的方法可以做到這一點嗎?

如何將此哈希轉換為數組?


在每個循環中,我都在做非常簡單的字符串操作:

name_hash.each {|name, str|

  record += name.to_s + "\|" + str +"\n"

}

哈希使用人們的名字作為關鍵字,一些相關的內容作為值:

name_hash = {:"jose garcia" => "ca:tw#2@1,2@:th#1@3@;ar:tw#1@4@:fi#1@5@;ny:tw#1@6@;"}

考慮以下示例,該示例使用一百萬個元素的哈希值:

#! /usr/bin/env ruby
require 'benchmark'

h = {}
1_000_000.times do |n|
  h[n] = rand
end

puts Benchmark.measure { h.each { |k, v| } }

a = nil
puts Benchmark.measure { a = h.to_a }
puts Benchmark.measure { a.each { |k, v| } }

我在工作中的系統上運行此文件(運行Ruby 1.8.5),得到:

  0.350000   0.020000   0.370000 (  0.380571)
  0.300000   0.020000   0.320000 (  0.307207)
  0.160000   0.040000   0.200000 (  0.198388)

因此,遍歷數組確實更快(散列為0.16秒,散列為0.35秒)。 但是生成陣列花費了0.3秒。 因此,凈過程比0.35秒慢了0.46秒。

因此看來,至少在此測試案例中,最好僅遍歷哈希。

在ruby中,更慣用的方法是:

record = name_hash.map{|k,v| "#{k}|#{v}"}.join("\n")

我不知道如何將它與速度進行比較,但是部分問題可能是因為您不斷在字符串上添加一些內容,並且每次迭代都創建新的(更長的)字符串對象。 聯接是用C語言完成的,可能會更好。

String#+很慢。 這應該改善它

 record = name_hash.map{|line| line.join("|")}.join("\n")

如果使用此方法輸出到某個地方,則不應創建巨大的字符串,而應逐行寫入輸出。

對大型集合進行迭代很慢,每種方法都無法解決問題。 您在循環中執行的操作是如此緩慢? 如果需要轉換為數組,可以通過調用some_hash.to_a

可能是“通過執行單個數據庫查詢”

將大型哈希轉換為數組將需要創建一個大型對象,並且將需要進行兩次迭代,盡管其中之一在解釋器內部並且可能非常快。

這不可能比僅在Hash上迭代要快,但可能適用於大型對象。

請查看標准庫基准測試包 ,以方便地測量運行時間。

我也敢冒險猜測,這里的真正問題是您有一個類似於Hash的ActiveRecord對象,該對象在枚舉的每個循環中都強制往返數據庫服務器。 這有可能是你真正想要的是繞過AR和運行本機查詢到在一個往返一次獲取的一切。

我以為ruby 1.9.x可以使哈希迭代更快,但可能是錯誤的。 如果是簡單的結構,則可以嘗試使用其他哈希,例如https://github.com/rdp/google_hash ,這是我為提高#each的可靠性而特意破解的哈希...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM