Ничего общего с рубиновыми внутренностями. Вы сравниваете яблоки с апельсинами.
в вашем первом примере вы группируете строку из 700 символов 100000 раз и находите количество. Так что проблема в вашей логике. не в счет. Во втором подходе вы просто считаете,
И в обоих подходах вы используете только счетчик
просто измените первый пример следующим образом
def count_frequency_using_chars(sequence)
grouped = sequence.chars.group_by{|x| x}
100000.times do
grouped.map{|letter, array| [letter, array.count]}
end
end
И это так же быстро, как ваш второй
Редактировать
Этот подход в 3 раза быстрее, чем count_frequency_using_count
, проверьте тесты
def count_frequency_using_chars_with_single_group(sequence)
grouped = sequence.chars.group_by{|x| x}
100000.times do
grouped.map{|letter, array| [letter, array.count]}
end
end
def count_frequency_using_count(sequence)
100000.times do
["a", "c", "g", "t"].map{|letter| sequence.count(letter)}
end
end
Benchmark.bm do |benchmark|
benchmark.report do
pp count_frequency_using_chars_with_single_group(sequence)
end
benchmark.report do
pp count_frequency_using_count(sequence)
end
end
user system total real
0.410000 0.000000 0.410000 ( 0.419100)
1.330000 0.000000 1.330000 ( 1.324431)
Андрей к вашим комментариям,
measuring the character composition of 100000 sequences once each, not the character composition of one sequence 100000 times
, но ваш подход к подсчету слишком медленный, чем подход group_by. Я только что проверил большие строки, как ты сказал
seq = "gattaca" * 10000
#seq length is 70000
arr_seq = (1..10).map {|x| seq}
#10 seq items
и изменил методы для обработки нескольких последовательностей
def count_frequency_using_chars_with_single_group(sequences)
sequences.each do |sequence|
grouped = sequence.chars.group_by{|x| x}
100000.times do
grouped.map{|letter, array| [letter, array.count]}
end
end
end
def count_frequency_using_count(sequence)
sequences.each do |sequence|
100000.times do
["a", "c", "g", "t"].map{|letter| sequence.count(letter)}
end
end
end
Benchmark.bm do |benchmark|
benchmark.report do
pp count_frequency_using_chars_with_single_group(arr_seq)
end
benchmark.report do
pp count_frequency_using_count(arr_seq)
end
end
Для обработки 100000 раз по 10 последовательностей длиной 70000
user system total real
3.710000 0.040000 3.750000 ( 23.452889) #modified group_by approach
1039.180000 6.920000 1046.100000 (1071.374730) #simple char count approach
Ваш простой метод подсчета символов на 47% медленнее, чем модифицированный подход group_by для строк большого объема. Я провел вышеупомянутый тест для всего 10 последовательностей длиной 70000 каждая. Предположим, это для 100 или 1000 последовательностей, простой счет никогда не будет возможным. право?