考虑这个:
first = %w[jane john]
last = %w[doe smith]
first.product(last)
# => [["jane", "doe"], ["jane", "smith"], ["john", "doe"], ["john", "smith"]]
你可以做这样的事情:
first = File.readlines('name.txt').map(&:rstrip)
last = File.readlines('last.txt').map(&:rstrip)
first.product(last)
product
是
所以,如果这样写你的代码可以更有效Array的一种方法。另外,也要看看permutation
和combination
。
我们可以用chomp
代替rstrip
删除尾随新线,这将是readlines
被退回,但chomp
只修剪新线,而rstrip
将删除尾随的空白,清理名字有点如果有任何尾随的空白。 (在我的经验它更可能我们将看到的文字比以前后的空白,因为它更容易看到,当它处于领先地位。)
基准:
require 'fruity'
FIRST_NAME = [*'a'..'z']
LAST_NAME = [*'a'..'z']
FIRST_NAME.size # => 26
LAST_NAME.size # => 26
def use_product
FIRST_NAME.product(LAST_NAME)
end
def use_loops
output = []
FIRST_NAME.each do |fn|
LAST_NAME.each do |ln|
output << [fn, ln]
end
end
output
end
result = use_product
result.size # => 676
result.first # => ["a", "a"]
result.last # => ["z", "z"]
result = use_loops
result.size # => 676
result.first # => ["a", "a"]
result.last # => ["z", "z"]
运行它导致:
compare :use_product, :use_loops
# >> Running each test 64 times. Test will take about 1 second.
# >> use_product is faster than use_loops by 50.0% ± 10.0%
如果在大小源阵列增加:
require 'fruity'
FIRST_NAME = [*'a1'..'z9']
LAST_NAME = [*'a1'..'z9']
FIRST_NAME.size # => 259
LAST_NAME.size # => 259
def use_product
FIRST_NAME.product(LAST_NAME)
end
def use_loops
output = []
FIRST_NAME.each do |fn|
LAST_NAME.each do |ln|
output << [fn, ln]
end
end
output
end
result = use_product
result.size # => 67081
result.first # => ["a1", "a1"]
result.last # => ["z9", "z9"]
result = use_loops
result.size # => 67081
result.first # => ["a1", "a1"]
result.last # => ["z9", "z9"]
运行返回:
compare :use_product, :use_loops
# >> Running each test once. Test will take about 1 second.
# >> use_product is faster than use_loops by 60.00000000000001% ± 10.0%
虽然我们可以编写算法没有考虑的内置方法的优势,该方法是用C写的所以利用它们来获取他们的加入了倍速。
有一段时间我会在内置的product
上使用单独数组的迭代:如果我有两个巨大的列表,并且由于RAM约束导致可伸缩性问题而将它们拉到内存中,那么只有这样才能处理它将是嵌套循环。 Ruby's foreach
is extremely fast,所以在它周围写代码将是一个很好的替代:
File.foreach('name.txt') do |first|
File.foreach('last.txt') do |last|
full_name = first.chomp + " " + last.chomp
puts full_name
end
end
啊!真棒,男人!谢谢! – user3610137
这样就打开了'last.txt'并且读取的是'''''''''''''''''这个效率相当低的数字。相反,将文件内容读入一个变量并在其上循环将会*效率更高,尤其是,当文件将变得更大时。 –
我同意。我没有去找高效的代码。我只是更新了他的当前代码来完成这项工作,在这种情况下,我只是添加了'.each'和他自己的代码,这个小改动:) –