From fce632fedf85e2f079dd424706fe5b5bbc0df3ce Mon Sep 17 00:00:00 2001 From: jer1ck0 <lex.lebedev@gmail.com> Date: Tue, 25 Jun 2024 13:20:33 +0300 Subject: [PATCH] ready --- case-study.md | 64 + profiler.rb | 8 + profiler1.rb | 22 + ram_spec.rb | 12 + ruby_prof_reports/callstack.html | 706 ++++++ ruby_prof_reports/flat.txt | 84 + ruby_prof_reports/graph.html | 4049 ++++++++++++++++++++++++++++++ ruby_prof_reports/graphviz.dot | 4 + task-2.rb | 188 +- 9 files changed, 5040 insertions(+), 97 deletions(-) create mode 100644 case-study.md create mode 100644 profiler.rb create mode 100644 profiler1.rb create mode 100644 ram_spec.rb create mode 100644 ruby_prof_reports/callstack.html create mode 100644 ruby_prof_reports/flat.txt create mode 100644 ruby_prof_reports/graph.html create mode 100644 ruby_prof_reports/graphviz.dot diff --git a/case-study.md b/case-study.md new file mode 100644 index 00000000..81f7003f --- /dev/null +++ b/case-study.md @@ -0,0 +1,64 @@ +## Формирование метрики +Для того, чтобы понимать, дают ли мои изменения положительный эффект на быстродействие программы я решил использовать такую метрику: Rspec тест проверяющий затрачиваемую память + +## Гарантия корректности работы оптимизированной программы +Программа поставлялась с тестом. Выполнение этого теста в фидбек-лупе позволяет не допустить изменения логики программы при оптимизации. + +## Feedback-Loop +Для того, чтобы иметь возможность быстро проверять гипотезы я выстроил эффективный `feedback-loop`, который позволил мне получать обратную связь по эффективности сделанных изменений за *время, которое у вас получилось* + +Вот как я построил `feedback_loop`: По примеру работы с первой задачей сделал выборки из data_large на + +## Вникаем в детали системы, чтобы найти главные точки роста +Для того, чтобы найти "точки роста" для оптимизации я воспользовался *инструментами, которыми вы воспользовались* + +Вот какие проблемы удалось найти и решить + +### Ваша находка №1 +- какой отчёт показал главную точку роста +- как вы решили её оптимизировать +- как изменилась метрика +- как изменился отчёт профилировщика + +### Ваша находка №2 +- какой отчёт показал главную точку роста +- как вы решили её оптимизировать +- как изменилась метрика +- как изменился отчёт профилировщика + +### Ваша находка №X +- какой отчёт показал главную точку роста +- как вы решили её оптимизировать +- как изменилась метрика +- как изменился отчёт профилировщика + +## Результаты +В результате проделанной оптимизации наконец удалось обработать файл с данными. +Удалось улучшить метрику системы с *того, что у вас было в начале, до того, что получилось в конце* и уложиться в заданный бюджет. + +*Какими ещё результами можете поделиться* + +## Защита от регрессии производительности +Для защиты от потери достигнутого прогресса при дальнейших изменениях программы *о performance-тестах, которые вы написали* + +### Ваша находка №1 +При первом прогоне профайлера выявлено значительное потребление памяти на сложении массивов(более 70 процентов потребления). + sessions = sessions + [parse_session(line)] if cols[0] == 'session' +В комментариях к выполнению задачи было указание на переписывание программы на потоковый стиль. +Начнем сразу +т.к в файлах данных строгая последовательность пользователь-сессия-сессия, то можно заинициализировать класс и добавлять в него данные по мере наполнения, а после полного сбора привести их к требуемому формату +### Ваша находка №2 +Таким образом мы обработаем второй тяжелый поинт из отчета не пробегая по массиву пользователей раз за разом +user_sessions = sessions.select { |session| session['user_id'] == user['id'] } +### Ваша находка №3 +При очередном прогоне теста было замечено высокое потребление на моменте перебора строк файла через each. Написав небольшой бенчмарк для сравнения скорости работы методов чтения из файла был получен метод foreach который в 8 раз быстрее обрабатывает файл построчно. +### Ваша находка №4 +Сначала я пытался добавлять пользователей в массив, дообогащать его рассчетами и записывать в файл преобразованное в json, +но при прогоне теста было большое потребление на обработку файловых операций. +Немного костыльными методами было решено разбить структуру предполагаемого файла на отдельные элементы, включая технические "{}, ", ," и дописывать в файл по мере необходимости. + +## Результаты +В результате проделанной оптимизации удалось обработать файл с данными 1кк c целевыми показателями по использованной памяти. Причем показатели потребления не меняются при увеличении обьема данных. + +## Примечания +При первой итерации пробовал пойти через перенос структуры данных в отдельные файлы. И гипотеза успешно отработала на файле до 1кк записей, но при увеличении объема затраты на запись и чтение свели весь прогресс на нет. \ No newline at end of file diff --git a/profiler.rb b/profiler.rb new file mode 100644 index 00000000..4d030c63 --- /dev/null +++ b/profiler.rb @@ -0,0 +1,8 @@ +require_relative 'task-2.rb' +require 'benchmark' +require 'memory_profiler' + +report = MemoryProfiler.report do + work(file_name: ARGV[0]) +end +report.pretty_print(scale_bytes: true) \ No newline at end of file diff --git a/profiler1.rb b/profiler1.rb new file mode 100644 index 00000000..61e92c8e --- /dev/null +++ b/profiler1.rb @@ -0,0 +1,22 @@ +require_relative 'task-2.rb' +require 'benchmark' +require 'ruby-prof' + + +RubyProf.measure_mode = RubyProf::ALLOCATIONS + +result = RubyProf.profile do + work(file_name: ARGV[0]) +end + +printer = RubyProf::FlatPrinter.new(result) +printer.print(File.open('ruby_prof_reports/flat.txt', 'w+')) + +# printer = RubyProf::DotPrinter.new(result) +# printer.print(File.open('ruby_prof_reports/graphviz.dot', 'w+')) + +printer = RubyProf::GraphHtmlPrinter.new(result) +printer.print(File.open('ruby_prof_reports/graph.html', 'w+')) + +printer = RubyProf::CallStackPrinter.new(result) +printer.print(File.open('ruby_prof_reports/callstack.html', 'w+')) \ No newline at end of file diff --git a/ram_spec.rb b/ram_spec.rb new file mode 100644 index 00000000..5c78207f --- /dev/null +++ b/ram_spec.rb @@ -0,0 +1,12 @@ +require 'rspec' +require 'rspec-benchmark' +require_relative 'task-2' + +RSpec.describe 'work' do + include RSpec::Benchmark::Matchers + + it 'requires < 60 Mb' do + work(file_name: 'data_large.txt') + expect((`ps -o rss= -p #{Process.pid}`.to_i / 1024)).to be < 60 + end +end diff --git a/ruby_prof_reports/callstack.html b/ruby_prof_reports/callstack.html new file mode 100644 index 00000000..2c9c542f --- /dev/null +++ b/ruby_prof_reports/callstack.html @@ -0,0 +1,706 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>ruby-prof call tree</title> + <style> + body { + font-size: 70%; + padding: 0; + margin: 5px; + margin-right: 0px; + margin-left: 0px; + background: #ffffff; + } + + ul { + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; + padding-left: 0px; + list-style-type: none; + font-weight: normal; + } + + li { + margin-left: 11px; + padding: 0px; + white-space: nowrap; + border-top: 1px solid #cccccc; + border-left: 1px solid #cccccc; + border-bottom: none; + } + + .thread { + margin-left: 11px; + background: #708090; + padding-top: 3px; + padding-left: 12px; + padding-bottom: 2px; + border-left: 1px solid #CCCCCC; + border-top: 1px solid #CCCCCC; + font-weight: bold; + } + + .hidden { + display: none; + width: 0px; + height: 0px; + margin: 0px; + padding: 0px; + border-style: none; + } + + .color01 { + background: #adbdeb + } + + .color05 { + background: #9daddb + } + + .color0 { + background: #8d9dcb + } + + .color1 { + background: #89bccb + } + + .color2 { + background: #56e3e7 + } + + .color3 { + background: #32cd70 + } + + .color4 { + background: #a3d53c + } + + .color5 { + background: #c4cb34 + } + + .color6 { + background: #dcb66d + } + + .color7 { + background: #cda59e + } + + .color8 { + background: #be9d9c + } + + .color9 { + background: #cf947a + } + + #commands { + font-size: 10pt; + padding: 10px; + margin-left: 11px; + margin-bottom: 0px; + margin-top: 0px; + background: #708090; + border-top: 1px solid #cccccc; + border-left: 1px solid #cccccc; + border-bottom: none; + } + + #titlebar { + font-size: 10pt; + padding: 10px; + margin-left: 11px; + margin-bottom: 0px; + margin-top: 10px; + background: #8090a0; + border-top: 1px solid #cccccc; + border-left: 1px solid #cccccc; + border-bottom: none; + } + + #help { + font-size: 10pt; + padding: 10px; + margin-left: 11px; + margin-bottom: 0px; + margin-top: 0px; + background: #8090a0; + display: none; + border-top: 1px solid #cccccc; + border-left: 1px solid #cccccc; + border-bottom: none; + } + + #sentinel { + height: 400px; + margin-left: 11px; + background: #8090a0; + border-top: 1px solid #cccccc; + border-left: 1px solid #cccccc; + border-bottom: none; + } + + input { + margin-left: 10px; + } + + .toggle { + background: url(data:image/png;base64,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) no-repeat left center; + float: left; + width: 9px; + height: 9px; + margin: 2px 1px 1px 1px; + } + + .toggle.minus { + background-position: -9px 0; + } + + .toggle.plus { + background-position: -18px 0; + } + </style> + + <script type="text/javascript"> + function rootNode() + { + return currentThread + } + + function showUL(node, show) + { + Array.prototype.forEach.call(node.childNodes, function(child) + { + if (child.nodeName == 'LI') + toggle(child, show) + }) + } + + function findUlChild(li) + { + var ul = li.childNodes[2] + while (ul && ul.nodeName != "UL") + { + ul = ul.nextSibling + } + return ul + } + + function isLeafNode(li) + { + var element = li.querySelector('a') + return element.classList.contains('empty') + } + + function toggle(li, show) + { + if (isLeafNode(li)) + return + + var img = li.firstChild + img.className = 'toggle ' + img.className += show ? 'minus' : 'plus' + + var ul = findUlChild(li) + if (ul) + { + ul.style.display = show ? 'block' : 'none' + showUL(ul, true) + } + } + + function toggleLI(li) + { + var img = li.firstChild + if (img.className.indexOf("minus") > -1) + toggle(li, false) + else + { + if (img.className.indexOf("plus") > -1) + toggle(li, true) + } + } + + function aboveThreshold(text, threshold) + { + var match = text.match(/\d+[.,]\d+%/) + if (!match) + { + return true + } + else + { + var value = parseFloat(match[0].replace(/,/, '.')) + return value >= threshold + } + } + + function setThresholdLI(li, threshold) + { + var a = li.querySelector('a') + var span = li.querySelector('span') + var ul = li.querySelector('ul') + + var visible = aboveThreshold(span.textContent, threshold) ? 1 : 0 + + var count = 0 + if (ul) + { + count = setThresholdUL(ul, threshold) + } + + if (count > 0) + { + a.className = 'toggle minus' + } + else + { + a.className = 'toggle empty' + } + + if (visible) + { + li.style.display = 'block' + } else + { + li.style.display = 'none' + } + return visible + } + + function setThresholdUL(node, threshold) + { + var count = 0 + Array.prototype.forEach.call(node.childNodes, function(child) + { + if (child.nodeName == 'LI') + count = count + setThresholdLI(child, threshold) + }) + + var visible = (count > 0) ? 1 : 0 + if (visible) + { + node.style.display = 'block' + } else + { + node.style.display = 'none' + } + return visible + } + + function toggleChildren(img, event) + { + event.cancelBubble = true + if (img.className.indexOf('empty') > -1) + return + + var minus = (img.className.indexOf('minus') > -1) + + if (minus) + { + img.className = 'toggle plus' + } else + img.className = 'toggle minus' + + var li = img.parentNode + var ul = findUlChild(li) + if (ul) + { + if (minus) + ul.style.display = 'none' + else + ul.style.display = 'block' + } + if (minus) + moveSelectionIfNecessary(li) + } + + function showChildren(li) + { + var img = li.firstChild + if (img.className.indexOf('empty') > -1) + return + img.className = 'toggle minus' + + var ul = findUlChild(li) + if (ul) + { + ul.style.display = 'block' + } + } + + function setThreshold() + { + var tv = document.getElementById("threshold").value + if (tv.match(/[0-9]+([.,][0-9]+)?/)) + { + var f = parseFloat(tv.replace(/,/, '.')) + var threads = document.getElementsByName("thread") + var l = threads.length + for (var i = 0; i < l; i++) + { + setThresholdUL(threads[i], f) + } + var p = selectedNode + while (p && p.style.display == 'none') + p = p.parentNode.parentNode + if (p && p.nodeName == "LI") + selectNode(p) + } else + { + alert("Please specify a decimal number as threshold value!") + } + } + + function expandAll(event) + { + toggleAll(event, true) + } + + function collapseAll(event) + { + toggleAll(event, false) + selectNode(rootNode(), null) + } + + function toggleAll(event, show) + { + event.cancelBubble = true + var threads = document.getElementsByName("thread") + var l = threads.length + for (var i = 0; i < l; i++) + { + showUL(threads[i], show) + } + } + + function toggleHelp(node) + { + var help = document.getElementById("help") + if (node.value == "Show Help") + { + node.value = "Hide Help" + help.style.display = 'block' + } else + { + node.value = "Show Help" + help.style.display = 'none' + } + } + + var selectedNode = null + var selectedColor = null + var selectedThread = null + + function descendentOf(a, b) + { + while (a != b && b != null) + b = b.parentNode + return (a == b) + } + + function moveSelectionIfNecessary(node) + { + if (descendentOf(node, selectedNode)) + selectNode(node, null) + } + + function selectNode(node, event) + { + if (event) + { + event.cancelBubble = true + thread = findThread(node) + selectThread(thread) + } + if (selectedNode) + { + selectedNode.style.background = selectedColor + } + selectedNode = node + selectedColor = node.style.background + selectedNode.style.background = "red" + selectedNode.scrollIntoView() + window.scrollBy(0, -400) + } + + function moveUp() + { + move(selectedNode.previousSibling) + } + + function moveDown() + { + move(selectedNode.nextSibling) + } + + function move(p) + { + while (p && p.style.display == 'none') + p = p.nextSibling + if (p && p.nodeName == "LI") + { + selectNode(p, null) + } + } + + function moveLeft() + { + var p = selectedNode.parentNode.parentNode + if (p && p.nodeName == "LI") + { + selectNode(p, null) + } + } + + function moveRight() + { + if (!isLeafNode(selectedNode)) + { + showChildren(selectedNode) + var ul = findUlChild(selectedNode) + if (ul) + { + selectNode(ul.firstChild, null) + } + } + } + + function moveForward() + { + if (isLeafNode(selectedNode)) + { + var p = selectedNode + while ((p.nextSibling == null || p.nextSibling.style.display == 'none') && p.nodeName == "LI") + { + p = p.parentNode.parentNode + } + if (p.nodeName == "LI") + selectNode(p.nextSibling, null) + } else + { + moveRight() + } + } + + function isExpandedNode(li) + { + var img = li.firstChild + return (img.className.indexOf('minus') > -1) + } + + function moveBackward() + { + var p = selectedNode + var q = p.previousSibling + while (q != null && q.style.display == 'none') + q = q.previousSibling + if (q == null) + { + p = p.parentNode.parentNode + } else + { + while (!isLeafNode(q) && isExpandedNode(q)) + { + q = findUlChild(q).lastChild + while (q.style.display == 'none') + q = q.previousSibling + } + p = q + } + if (p.nodeName == "LI") + selectNode(p, null) + } + + function moveHome() + { + selectNode(currentThread) + } + + var currentThreadIndex = null + + function findThread(node) + { + while (node && !node.parentNode.nodeName.match(/BODY|DIV/g)) + { + node = node.parentNode + } + return node.firstChild + } + + function selectThread(node) + { + var threads = document.getElementsByName("thread") + currentThread = node + for (var i = 0; i < threads.length; i++) + { + if (threads[i] == currentThread.parentNode) + currentThreadIndex = i + } + } + + function nextThread() + { + var threads = document.getElementsByName("thread") + if (currentThreadIndex == threads.length - 1) + currentThreadIndex = 0 + else + currentThreadIndex += 1 + currentThread = threads[currentThreadIndex].firstChild + selectNode(currentThread, null) + } + + function previousThread() + { + var threads = document.getElementsByName("thread") + if (currentThreadIndex == 0) + currentThreadIndex = threads.length - 1 + else + currentThreadIndex -= 1 + currentThread = threads[currentThreadIndex].firstChild + selectNode(currentThread, null) + } + + function switchThread(node, event) + { + event.cancelBubble = true + selectThread(node.nextSibling.firstChild) + selectNode(currentThread, null) + } + + function handleKeyEvent(event) + { + var code = event.charCode ? event.charCode : event.keyCode + var str = String.fromCharCode(code) + switch (str) + { + case "a": + moveLeft() + break + case "s": + moveDown() + break + case "d": + moveRight() + break + case "w": + moveUp() + break + case "f": + moveForward() + break + case "b": + moveBackward() + break + case "x": + toggleChildren(selectedNode.firstChild, event) + break + case "*": + toggleLI(selectedNode) + break + case "n": + nextThread() + break + case "h": + moveHome() + break + case "p": + previousThread() + break + } + } + + document.onkeypress = function (event) + { + handleKeyEvent(event) + } + + window.onload = function () + { + var images = document.querySelectorAll(".toggle") + for (var i = 0; i < images.length; i++) + { + var img = images[i] + img.onclick = function (event) + { + toggleChildren(this, event) + return false + } + } + var divs = document.getElementsByTagName("div") + for (i = 0; i < divs.length; i++) + { + var div = divs[i] + if (div.className == "thread") + div.onclick = function (event) + { + switchThread(this, event) + } + } + var lis = document.getElementsByTagName("li") + for (var i = 0; i < lis.length; i++) + { + lis[i].onclick = function (event) + { + selectNode(this, event) + } + } + + var threads = document.getElementsByName("thread") + currentThreadIndex = 0 + currentThread = threads[0].querySelector('li') + selectNode(currentThread, null) + } + </script> + + + </head> + <body> + <div style="display: inline-block;"> + <div id="titlebar"> + Call tree for application <strong>profiler1.rb data_large.txt</strong><br/> Generated on 2024-06-25 11:49:02 +0300 + with options {}<br/> + </div> + <div id="commands"> + <span style="font-size: 11pt; font-weight: bold;">Threshold:</span> + <input value="1.0" size="3" id="threshold" type="text"> + <input value="Apply" onclick="setThreshold();" type="submit"> + <input value="Expand All" onclick="expandAll(event);" type="submit"> + <input value="Collapse All" onclick="collapseAll(event);" type="submit"> + <input value="Show Help" onclick="toggleHelp(this);" type="submit"> + </div> + <ul style="display: none;" id="help"> + <li>* indicates recursively called methods</li> + <li>Enter a decimal value <i>d</i> into the threshold field and click "Apply" to hide all nodes marked with time + values lower than <em>d</em>. + </li> + <li>Click on "Expand All" for full tree expansion.</li> + <li>Click on "Collapse All" to show only top level nodes.</li> + <li>Use a, s, d, w as in Quake or Urban Terror to navigate the tree.</li> + <li>Use f and b to navigate the tree in preorder forward and backwards.</li> + <li>Use x to toggle visibility of a subtree.</li> + <li>Use * to expand/collapse a whole subtree.</li> + <li>Use h to navigate to thread root.</li> + <li>Use n and p to navigate between threads.</li> + <li>Click on background to move focus to a subtree.</li> + </ul> + + + + <div class="thread"> + <span>Thread: 260, Fiber: 240 ( NaN% ~ 0.0)</span> + <ul name="thread"> + + + </ul> + </div> + + <div id="sentinel"></div> + </div> + </body> +</html> diff --git a/ruby_prof_reports/flat.txt b/ruby_prof_reports/flat.txt new file mode 100644 index 00000000..d64da3a0 --- /dev/null +++ b/ruby_prof_reports/flat.txt @@ -0,0 +1,84 @@ +Measure Mode: allocations +Thread ID: 260 +Fiber ID: 240 +Total: 0.000000 +Sort by: self_time + + %self total self wait child calls name location + NaN 0.000 0.000 0.000 0.000 1 String#% + NaN 0.000 0.000 0.000 0.000 1 Integer#/ + NaN 0.000 0.000 0.000 0.000 1 Kernel#` + NaN 0.000 0.000 0.000 0.000 1 <Module::Process>#pid + NaN 0.000 0.000 0.000 0.000 3 Integer#inspect + NaN 0.000 0.000 0.000 0.000 5 String#inspect + NaN 0.000 0.000 0.000 0.000 1 Hash#to_s + NaN 0.000 0.000 0.000 0.000 3 IO#puts + NaN 0.000 0.000 0.000 0.000 3 Kernel#puts + NaN 0.000 0.000 0.000 0.000 1 IO#close + NaN 0.000 0.000 0.000 0.000 1 String#to_s + NaN 0.000 0.000 0.000 0.000 1 String#slice + NaN 0.000 0.000 0.000 0.000 1 Array#size + NaN 0.000 0.000 0.000 0.000 500000 User#sessions= + NaN 0.000 0.000 0.000 0.000 500000 Integer#- + NaN 0.000 0.000 0.000 0.000 500000 String#length + NaN 0.000 0.000 0.000 0.000 1000000 String#== + NaN 0.000 0.000 0.000 0.000 1500000 String#[] + NaN 0.000 0.000 0.000 0.000 500001 JSON::Ext::Generator::State#initialize + NaN 0.000 0.000 0.000 0.000 500001 JSON::Ext::Generator::GeneratorMethods::Hash#to_json + NaN 0.000 0.000 0.000 0.000 500000 Integer#> + NaN 0.000 0.000 0.000 0.000 500000 Object#save_user /mnt/c/Users/Home/study/mytask-2/task-2.rb:74 + NaN 0.000 0.000 0.000 0.000 500000 Array#reverse! + NaN 0.000 0.000 0.000 0.000 500001 Array#sort! + NaN 0.000 0.000 0.000 0.000 500001 Array#join + NaN 0.000 0.000 0.000 0.000 500000 Array#sort + NaN 0.000 0.000 0.000 0.000 500000 Array#all? + NaN 0.000 0.000 0.000 0.000 2075737 String#=~ + NaN 0.000 0.000 0.000 0.000 500000 Array#any? + NaN 0.000 0.000 0.000 0.000 2750940 BasicObject#! + NaN 0.000 0.000 0.000 0.000 2750940 Array#include? + NaN 0.000 0.000 0.000 0.000 2750940 String#upcase! + NaN 0.000 0.000 0.000 0.000 2750940 Integer#< + NaN 0.000 0.000 0.000 0.000 2750941 String#to_i + NaN 0.000 0.000 0.000 0.000 500000 Array#each + NaN 0.000 0.000 0.000 0.000 500000 Enumerable#inject + NaN 0.000 0.000 0.000 0.000 8253020 Array#<< + NaN 0.000 0.000 0.000 0.000 2750940 Object#parse_session /mnt/c/Users/Home/study/mytask-2/task-2.rb:25 + NaN 0.000 0.000 0.000 0.000 3250940 User#sessions + NaN 0.000 0.000 0.000 0.000 8752820 Hash#[]= + NaN 0.000 0.000 0.000 0.000 8752820 Integer#+ + NaN 0.000 0.000 0.000 0.000 8752820 Hash#[] + NaN 0.000 0.000 0.000 0.000 1000000 User#attributes= + NaN 0.000 0.000 0.000 0.000 1000000 String#<< + NaN 0.000 0.000 0.000 0.000 500000 Object#parse_user /mnt/c/Users/Home/study/mytask-2/task-2.rb:17 + NaN 0.000 0.000 0.000 0.000 1000001 User#attributes + NaN 0.000 0.000 0.000 0.000 500001 Object#collect_stats_from_users /mnt/c/Users/Home/study/mytask-2/task-2.rb:35 + NaN 0.000 0.000 0.000 0.000 3250940 String#split + NaN 0.000 0.000 0.000 0.000 3250940 String#chop + NaN 0.000 0.000 0.000 0.000 1 <Class::IO>#foreach + NaN 0.000 0.000 0.000 0.000 1 User#initialize /mnt/c/Users/Home/study/mytask-2/task-2.rb:11 + NaN 0.000 0.000 0.000 0.000 1 Class#new + NaN 0.000 0.000 0.000 0.000 1000005 IO#write + NaN 0.000 0.000 0.000 0.000 1 File#initialize + NaN 0.000 0.000 0.000 0.000 1 <Class::IO>#open + NaN 0.000 0.000 0.000 0.000 1 Object#work /mnt/c/Users/Home/study/mytask-2/task-2.rb:85 + NaN 0.000 0.000 0.000 0.000 19005641 Array#[] + NaN 0.000 0.000 0.000 0.000 1 [global]# profiler1.rb:9 + +* recursively called methods + +Columns are: + + %self - The percentage of time spent in this method, derived from self_time/total_time. + total - The time spent in this method and its children. + self - The time spent in this method. + wait - The amount of time this method waited for other threads. + child - The time spent in this method's children. + calls - The number of times this method was called. + name - The name of the method. + location - The location of the method. + +The interpretation of method names is: + + * MyObject#test - An instance method "test" of the class "MyObject" + * <Object:MyObject>#test - The <> characters indicate a method on a singleton class. + diff --git a/ruby_prof_reports/graph.html b/ruby_prof_reports/graph.html new file mode 100644 index 00000000..aa406223 --- /dev/null +++ b/ruby_prof_reports/graph.html @@ -0,0 +1,4049 @@ +<!DOCTYPE html> +<html> +<head> + <style media="all" type="text/css"> + body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + background-color: #F5F7FB; + margin: 0; + padding: 0; + font-size: 16px; + } + + table { + border-collapse: collapse; + /* border: 1px solid #E1E3E7; */ + border: 1px solid #F3F9FE; + font-size: 14px; + line-height: normal; + width: 100%; + } + + table:empty { + display: none; + } + + th:first-child { + border-left: 0; + } + + th { + text-align: center; + background: #F3F9FE; + padding: 1rem; + /* border-left: 1px solid #E1E3E7; */ + text-transform: uppercase; + font-size: 13px; + letter-spacing: 1px; + } + + tr.break td { + border: 0; + border-top: 1px solid #BDC3DD; + padding: 0; + margin: 0; + } + + tr.method td { + font-weight: bold; + } + + td { + padding: 0.5em; + } + + td:first-child { + width: 190px; + } + + tr > td > table { + box-shadow: 0px -2px 1px #F9FAFB, 0px 1px 1px #E4EEEE, 0px 1px 2px #EEF3F8; + border-radius: 2px; + overflow: hidden; + } + + tr.break + tr > td.method_name { + font-weight: bold; + } + + td { + /* I'm removing this border because I think it looks way cleaner without it but feel free to add it if you feel it's necessary */ + /* border-left: 1px solid #E1E3E7; */ + text-align: center; + } + + a { + text-decoration: none; + } + + .method_name { + text-align: left; + } + + tfoot td { + text-align: left; + } + + .report-header { + background-color: #0D2483; + color: white; + padding: 1.5rem 2rem; + } + + .report-header > div { + display: flex; + flex-direction: row; + align-items: center; + } + + .report-header h1 { + margin-bottom: 0; + } + + h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5rem; + } + + h6 { + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 1.5px; + color: rgba(255, 255, 255, 0.6); + } + + .table-header { + padding: 3rem 0 1rem; + } + + .table-wrapper { + margin: 1rem auto; + max-width: 1440px; + padding: 4rem 5rem; + background: white; + border-radius: 0.5rem; + } + + .center { + max-width: 1440px; + margin: 0 auto; + } + + .layout-right { + margin-left: auto; + } + + .text-right { + display: flex; + align-items: flex-end; + flex-direction: column; + } + + .timestamp { + font-size: 12px; + margin-bottom: 1rem; + color: rgba(255, 255, 255, 0.6); + } + + .logo { + width: 140px; + height: 30px; + opacity: 0.5; + background-repeat: no-repeat; + background-image: url("data:image/svg+xml,%3Csvg id='Layer_1' data-name='Layer 1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 190 41'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23fff%7D%3C/style%3E%3C/defs%3E%3Cpath class='cls-1' d='M63.49 16.74c0-1.37-.91-2-2.26-2h-3.38v3.93h3.58c1.24.01 2.06-.56 2.06-1.93zM110.43 14.75h-3.6v5h3.6a2.32 2.32 0 0 0 2.5-2.49 2.34 2.34 0 0 0-2.5-2.51zM128.77 14.75h-3.53v4.94h3.53a2.28 2.28 0 0 0 2.47-2.45 2.3 2.3 0 0 0-2.47-2.49zM61.81 21.83h-4v4.32h3.91c1.44 0 2.45-.62 2.45-2.14s-.99-2.18-2.36-2.18zM21 14.75h-3.57v4.94H21a2.28 2.28 0 0 0 2.47-2.45A2.3 2.3 0 0 0 21 14.75z'/%3E%3Cpath class='cls-1' d='M184 .44H5.87A4.93 4.93 0 0 0 .94 5.37V35.5a4.94 4.94 0 0 0 4.93 4.94H184a4.94 4.94 0 0 0 4.94-4.94V5.37A4.94 4.94 0 0 0 184 .44zm-34.38 10.78c4.79 0 8.46 2.89 9.18 7.54h-3.86a5.48 5.48 0 0 0-10.68 0h-3.83c.71-4.65 4.36-7.54 9.19-7.54zM24 29.44L20.46 23h-3v6.46h-3.72v-18h7.68c3.41 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.82 7.06zm24.31-7.3c0 4.8-2.92 7.56-7.63 7.56S33 26.94 33 22.14V11.48h3.69v10.61c0 2.81 1.37 4.32 4 4.32s3.94-1.51 3.94-4.32V11.48h3.69zm13.92 7.3h-8v-18h7.52c3.24 0 5.59 1.61 5.59 5A4 4 0 0 1 65.51 20 4.22 4.22 0 0 1 68 24.21c0 3.43-2.4 5.23-5.81 5.23zm19.66-6.92v6.92h-3.7v-6.92l-6.81-11h4.29L80 18.85l4.34-7.37h4.32zm16-.5h-7.62v-3.26h7.59zm13 1h-4v6.39h-3.72v-18h7.77c3.41 0 5.79 2.09 5.79 5.79s-2.41 5.85-5.82 5.85zm20.86 6.39L128.26 23h-3v6.46h-3.72v-18h7.69c3.4 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.87 7.08zm17.85.26c-4.88 0-8.55-2.95-9.21-7.68h3.81A5.49 5.49 0 0 0 155 22h3.84c-.69 4.75-4.38 7.7-9.22 7.7zm18.4-.23h-3.72v-3.7H168zm6.36-7.54h-10.05v-3.26h10.08zm1.44-7.16h-11.49v-3.26h11.52z'/%3E%3C/svg%3E"); + } + </style> +</head> +<body> +<div class="report-header"> + <div class="center"> + <div class="layout-left"> + <h6>Profile Report</h6> + <h1>Allocations</h1> + </div> + <div class="layout-right text-right"> + <div class="timestamp">Tuesday, June 25 at 11:49:02 AM (MSK)</div> + <div class="logo"></div> + </div> + </div> +</div> +<div class="table-wrapper"> + <table> + <tr> + <th>Thread ID</th> + <th>Fiber ID</th> + <th>Total</th> + </tr> + + <tr> + <td>260</td> + <td><a href="#240">240</a></td> + <td>0.0</td> + </tr> + + </table> + + <!-- Methods Tables --> + + <h2><a name="240">Thread 260, Fiber: 240</a></h2> + <table> + <thead> + <tr> + <th>%Total</th> + <th>%Self</th> + <th>Total</th> + <th>Self</th> + <th>Wait</th> + <th>Child</th> + <th>Calls</th> + <th class="method_name">Name</th> + + <th>Line</th> + </tr> + </thead> + <tbody> + + + <!-- Parents --> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="[global]__240"> + [global]# + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/profiler1.rb#9" title="/mnt/c/Users/Home/study/mytask-2/profiler1.rb:9">9</a></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/profiler1.rb#9" title="/mnt/c/Users/Home/study/mytask-2/profiler1.rb:9">9</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/19005641</td> + <td class="method_name"><a href="#Array_[]_240">Array#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/profiler1.rb#9" title="/mnt/c/Users/Home/study/mytask-2/profiler1.rb:9">9</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#[global]__240">[global]#</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/profiler1.rb#9" title="/mnt/c/Users/Home/study/mytask-2/profiler1.rb:9">9</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="Object_work_240"> + Object#work + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#85" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:85">85</a></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#String_%_240">String#%</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Integer_/_240">Integer#/</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/2750941</td> + <td class="method_name"><a href="#String_to_i_240">String#to_i</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Kernel_`_240">Kernel#`</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#_Module__Process__pid_240"><Module::Process>#pid</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/3</td> + <td class="method_name"><a href="#Kernel_puts_240">Kernel#puts</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#121" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:121">121</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#IO_close_240">IO#close</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#119" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:119">119</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#String_to_s_240">String#to_s</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#118" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:118">118</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#String_slice_240">String#slice</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#118" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:118">118</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#JSON__Ext__Generator__GeneratorMethods__Hash_to_json_240">JSON::Ext::Generator::GeneratorMethods::Hash#to_json</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#118" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:118">118</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Array_join_240">Array#join</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#115" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:115">115</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Array_sort!_240">Array#sort!</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#115" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:115">115</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Array_size_240">Array#size</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#114" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:114">114</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#112" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:112">112</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#98" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:98">98</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Class_new_240">Class#new</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#96" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:96">96</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/1000005</td> + <td class="method_name"><a href="#IO_write_240">IO#write</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#94" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:94">94</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#_Class__IO__open_240"><Class::IO>#open</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#93" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:93">93</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/19005641</td> + <td class="method_name"><a href="#[global]__240">[global]#</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/profiler1.rb#9" title="/mnt/c/Users/Home/study/mytask-2/profiler1.rb:9">9</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/19005641</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2000000/19005641</td> + <td class="method_name"><a href="#Object_parse_user_240">Object#parse_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#19" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:19">19</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>13754700/19005641</td> + <td class="method_name"><a href="#Object_parse_session_240">Object#parse_session</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#27" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:27">27</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>19005641</td> + <td class="method_name"> + <a name="Array_[]_240"> + Array#[] + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#118" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:118">118</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="String_to_s_240"> + String#to_s + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750941</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/2750941</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750941</td> + <td class="method_name"> + <a name="String_to_i_240"> + String#to_i + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#118" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:118">118</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="String_slice_240"> + String#slice + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="String_%_240"> + String#% + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#112" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:112">112</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001</td> + <td class="method_name"> + <a name="Object_collect_stats_from_users_240"> + Object#collect_stats_from_users + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#35" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:35">35</a></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#71" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:71">71</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Array_reverse!_240">Array#reverse!</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#69" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:69">69</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#Array_sort!_240">Array#sort!</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#69" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:69">69</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#Array_join_240">Array#join</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#68" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:68">68</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Array_sort_240">Array#sort</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#68" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:68">68</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Array_all__240">Array#all?</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#64" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:64">64</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Array_any__240">Array#any?</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#62" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:62">62</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Enumerable_inject_240">Enumerable#inject</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#38" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:38">38</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/3250940</td> + <td class="method_name"><a href="#User_sessions_240">User#sessions</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#38" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:38">38</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001/1000001</td> + <td class="method_name"><a href="#User_attributes_240">User#attributes</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#36" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:36">36</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/3</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#121" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:121">121</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3</td> + <td class="method_name"> + <a name="Kernel_puts_240"> + Kernel#puts + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/3</td> + <td class="method_name"><a href="#IO_puts_240">IO#puts</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="Kernel_`_240"> + Kernel#` + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#78" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:78">78</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#118" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:118">118</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001</td> + <td class="method_name"> + <a name="JSON__Ext__Generator__GeneratorMethods__Hash_to_json_240"> + JSON::Ext::Generator::GeneratorMethods::Hash#to_json + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001/500001</td> + <td class="method_name"><a href="#JSON__Ext__Generator__State_initialize_240">JSON::Ext::Generator::State#initialize</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="Integer_/_240"> + Integer#/ + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/1000005</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#94" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:94">94</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>999999/1000005</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#80" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:80">80</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/1000005</td> + <td class="method_name"><a href="#IO_puts_240">IO#puts</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000005</td> + <td class="method_name"> + <a name="IO_write_240"> + IO#write + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#119" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:119">119</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="IO_close_240"> + IO#close + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#96" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:96">96</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="Class_new_240"> + Class#new + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#User_initialize_240">User#initialize</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#69" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:69">69</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#115" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:115">115</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001</td> + <td class="method_name"> + <a name="Array_sort!_240"> + Array#sort! + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#114" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:114">114</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="Array_size_240"> + Array#size + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#68" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:68">68</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/500001</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#115" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:115">115</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001</td> + <td class="method_name"> + <a name="Array_join_240"> + Array#join + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#139" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:139">139</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="_Module__Process__pid_240"> + <Module::Process>#pid + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#93" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:93">93</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="_Class__IO__open_240"> + <Class::IO>#open + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#File_initialize_240">File#initialize</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Object_work_240">Object#work</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#98" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:98">98</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="_Class__IO__foreach_240"> + <Class::IO>#foreach + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/8253020</td> + <td class="method_name"><a href="#Array____240">Array#<<</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#102" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:102">102</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Object_parse_session_240">Object#parse_session</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#102" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:102">102</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/3250940</td> + <td class="method_name"><a href="#User_sessions_240">User#sessions</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#102" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:102">102</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/8752820</td> + <td class="method_name"><a href="#Hash_[]__240">Hash#[]=</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#108" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:108">108</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/8752820</td> + <td class="method_name"><a href="#Integer_+_240">Integer#+</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#108" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:108">108</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/8752820</td> + <td class="method_name"><a href="#Hash_[]_240">Hash#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#108" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:108">108</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/1000000</td> + <td class="method_name"><a href="#User_attributes__240">User#attributes=</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#107" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:107">107</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_parse_user_240">Object#parse_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#107" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:107">107</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#105" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:105">105</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/19005641</td> + <td class="method_name"><a href="#Array_[]_240">Array#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#100" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:100">100</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/3250940</td> + <td class="method_name"><a href="#String_split_240">String#split</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#99" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:99">99</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/3250940</td> + <td class="method_name"><a href="#String_chop_240">String#chop</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#99" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:99">99</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/3250940</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/3250940</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#38" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:38">38</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940</td> + <td class="method_name"> + <a name="User_sessions_240"> + User#sessions + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Class_new_240">Class#new</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="User_initialize_240"> + User#initialize + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#11" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:11">11</a></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/1000000</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/1000000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#82" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:82">82</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000</td> + <td class="method_name"> + <a name="User_attributes__240"> + User#attributes= + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001/1000001</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#36" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:36">36</a></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/1000001</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#77" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:77">77</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000001</td> + <td class="method_name"> + <a name="User_attributes_240"> + User#attributes + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/3250940</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940</td> + <td class="method_name"> + <a name="String_split_240"> + String#split + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/3250940</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940</td> + <td class="method_name"> + <a name="String_chop_240"> + String#chop + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#71" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:71">71</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Object_save_user_240"> + Object#save_user + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#74" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:74">74</a></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/1000000</td> + <td class="method_name"><a href="#User_attributes__240">User#attributes=</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#82" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:82">82</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#User_sessions__240">User#sessions=</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#81" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:81">81</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>999999/1000005</td> + <td class="method_name"><a href="#IO_write_240">IO#write</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#80" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:80">80</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Integer_-_240">Integer#-</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#String_length_240">String#length</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000/1000000</td> + <td class="method_name"><a href="#String____240">String#==</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1500000/1500000</td> + <td class="method_name"><a href="#String_[]_240">String#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500001</td> + <td class="method_name"><a href="#JSON__Ext__Generator__GeneratorMethods__Hash_to_json_240">JSON::Ext::Generator::GeneratorMethods::Hash#to_json</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#78" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:78">78</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/1000001</td> + <td class="method_name"><a href="#User_attributes_240">User#attributes</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#77" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:77">77</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Integer___240">Integer#></a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#75" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:75">75</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Object_parse_user_240"> + Object#parse_user + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#17" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:17">17</a></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000/1000000</td> + <td class="method_name"><a href="#String____240">String#<<</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#19" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:19">19</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2000000/19005641</td> + <td class="method_name"><a href="#Array_[]_240">Array#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#19" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:19">19</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940</td> + <td class="method_name"> + <a name="Object_parse_session_240"> + Object#parse_session + </a> + </td> + + + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#25" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:25">25</a></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>13754700/19005641</td> + <td class="method_name"><a href="#Array_[]_240">Array#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#27" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:27">27</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001/500001</td> + <td class="method_name"><a href="#JSON__Ext__Generator__GeneratorMethods__Hash_to_json_240">JSON::Ext::Generator::GeneratorMethods::Hash#to_json</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500001</td> + <td class="method_name"> + <a name="JSON__Ext__Generator__State_initialize_240"> + JSON::Ext::Generator::State#initialize + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/8752820</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5501880/8752820</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>8752820</td> + <td class="method_name"> + <a name="Integer_+_240"> + Integer#+ + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/3</td> + <td class="method_name"><a href="#Kernel_puts_240">Kernel#puts</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3</td> + <td class="method_name"> + <a name="IO_puts_240"> + IO#puts + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#Hash_to_s_240">Hash#to_s</a></td> + + <td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/1000005</td> + <td class="method_name"><a href="#IO_write_240">IO#write</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/8752820</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5501880/8752820</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>8752820</td> + <td class="method_name"> + <a name="Hash_[]__240"> + Hash#[]= + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3250940/8752820</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5501880/8752820</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>8752820</td> + <td class="method_name"> + <a name="Hash_[]_240"> + Hash#[] + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#_Class__IO__open_240"><Class::IO>#open</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="File_initialize_240"> + File#initialize + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#38" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:38">38</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Enumerable_inject_240"> + Enumerable#inject + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#68" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:68">68</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Array_sort_240"> + Array#sort + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#69" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:69">69</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Array_reverse!_240"> + Array#reverse! + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#62" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:62">62</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Array_any__240"> + Array#any? + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1431949/2075737</td> + <td class="method_name"><a href="#String__~_240">String#=~</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#62" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:62">62</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_collect_stats_from_users_240">Object#collect_stats_from_users</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#64" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:64">64</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Array_all__240"> + Array#all? + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>643788/2075737</td> + <td class="method_name"><a href="#String__~_240">String#=~</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#64" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:64">64</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/8253020</td> + <td class="method_name"><a href="#_Class__IO__foreach_240"><Class::IO>#foreach</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5502080/8253020</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>8253020</td> + <td class="method_name"> + <a name="Array____240"> + Array#<< + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#81" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:81">81</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="User_sessions__240"> + User#sessions= + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="String_length_240"> + String#length + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1500000/1500000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1500000</td> + <td class="method_name"> + <a name="String_[]_240"> + String#[] + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1431949/2075737</td> + <td class="method_name"><a href="#Array_any__240">Array#any?</a></td> + + <td></td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>643788/2075737</td> + <td class="method_name"><a href="#Array_all__240">Array#all?</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2075737</td> + <td class="method_name"> + <a name="String__~_240"> + String#=~ + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000/1000000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000</td> + <td class="method_name"> + <a name="String____240"> + String#== + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000/1000000</td> + <td class="method_name"><a href="#Object_parse_user_240">Object#parse_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#19" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:19">19</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1000000</td> + <td class="method_name"> + <a name="String____240"> + String#<< + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#75" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:75">75</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Integer___240"> + Integer#> + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Object_save_user_240">Object#save_user</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#79" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:79">79</a></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Integer_-_240"> + Integer#- + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1/1</td> + <td class="method_name"><a href="#IO_puts_240">IO#puts</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>1</td> + <td class="method_name"> + <a name="Hash_to_s_240"> + Hash#to_s + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/3</td> + <td class="method_name"><a href="#Integer_inspect_240">Integer#inspect</a></td> + + <td> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5/5</td> + <td class="method_name"><a href="#String_inspect_240">String#inspect</a></td> + + <td> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000/500000</td> + <td class="method_name"><a href="#Enumerable_inject_240">Enumerable#inject</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>500000</td> + <td class="method_name"> + <a name="Array_each_240"> + Array#each + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#BasicObject_!_240">BasicObject#!</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#57" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:57">57</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Array_include__240">Array#include?</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#57" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:57">57</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5502080/8253020</td> + <td class="method_name"><a href="#Array____240">Array#<<</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#55" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:55">55</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#String_upcase!_240">String#upcase!</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#55" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:55">55</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Integer___240">Integer#<</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#54" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:54">54</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750941</td> + <td class="method_name"><a href="#String_to_i_240">String#to_i</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#52" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:52">52</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5501880/8752820</td> + <td class="method_name"><a href="#Hash_[]__240">Hash#[]=</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#51" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:51">51</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5501880/8752820</td> + <td class="method_name"><a href="#Integer_+_240">Integer#+</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#51" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:51">51</a> + </tr> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5501880/8752820</td> + <td class="method_name"><a href="#Hash_[]_240">Hash#[]</a></td> + + <td><a href="file:///mnt/c/Users/Home/study/mytask-2/task-2.rb#51" title="/mnt/c/Users/Home/study/mytask-2/task-2.rb:51">51</a> + </tr> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940</td> + <td class="method_name"> + <a name="String_upcase!_240"> + String#upcase! + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5/5</td> + <td class="method_name"><a href="#Hash_to_s_240">Hash#to_s</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>5</td> + <td class="method_name"> + <a name="String_inspect_240"> + String#inspect + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3/3</td> + <td class="method_name"><a href="#Hash_to_s_240">Hash#to_s</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>3</td> + <td class="method_name"> + <a name="Integer_inspect_240"> + Integer#inspect + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940</td> + <td class="method_name"> + <a name="Integer___240"> + Integer#< + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940</td> + <td class="method_name"> + <a name="BasicObject_!_240"> + BasicObject#! + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + + <!-- Parents --> + + <tr> + <td> </td> + <td> </td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940/2750940</td> + <td class="method_name"><a href="#Array_each_240">Array#each</a></td> + + <td></td> + </tr> + + <tr class="method"> + <td>NaN%</td> + <td>NaN%</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>0.00</td> + <td>2750940</td> + <td class="method_name"> + <a name="Array_include__240"> + Array#include? + </a> + </td> + + + + <td></td> + </tr> + + + + <!-- Children --> + + + <!-- Create divider row --> + <tr class="break"> + <td colspan="10"></td> + </tr> + + </tbody> + <tfoot> + <tr> + <td colspan="9">* indicates recursively called methods</td> + </tr> + </tfoot> + </table> + +</div> + +<script type="application/javascript"> + function toggleAllocations(element) + { + if (element.style.display == 'none') + element.style.display = 'block' + else + element.style.display = 'none' + } + + function onClick(event) + { + if (event.target.tagName == 'A' && event.target.classList.contains('allocations')) + { + var url = new URL(event.target.href) + var element = document.querySelector(url.hash) + toggleAllocations(element) + event.preventDefault() + } + } + + window.addEventListener('DOMContentLoaded', function(event) + { + document.addEventListener('click', onClick) + }) + +</script> +</body> +</html> diff --git a/ruby_prof_reports/graphviz.dot b/ruby_prof_reports/graphviz.dot new file mode 100644 index 00000000..0d9b6a50 --- /dev/null +++ b/ruby_prof_reports/graphviz.dot @@ -0,0 +1,4 @@ +digraph "Profile" { +labelloc=t; +labeljust=l; +subgraph "Thread 260" { diff --git a/task-2.rb b/task-2.rb index 34e09a3c..9e1d30c4 100644 --- a/task-2.rb +++ b/task-2.rb @@ -6,7 +6,7 @@ require 'minitest/autorun' class User - attr_reader :attributes, :sessions + attr_accessor :attributes, :sessions def initialize(attributes:, sessions:) @attributes = attributes @@ -15,46 +15,110 @@ def initialize(attributes:, sessions:) end def parse_user(user) - fields = user.split(',') - parsed_result = { - 'id' => fields[1], - 'first_name' => fields[2], - 'last_name' => fields[3], - 'age' => fields[4], + { + 'id' => user[1], + 'full_name' => user[2] << ' ' << user[3], + 'age' => user[4], } end def parse_session(session) - fields = session.split(',') - parsed_result = { - 'user_id' => fields[1], - 'session_id' => fields[2], - 'browser' => fields[3], - 'time' => fields[4], - 'date' => fields[5], + { + 'user_id' => session[1], + 'session_id' => session[2], + 'browser' => session[3], + 'time' => session[4], + 'date' => session[5], } end -def collect_stats_from_users(report, users_objects, &block) - users_objects.each do |user| - user_key = "#{user.attributes['first_name']}" + ' ' + "#{user.attributes['last_name']}" - report['usersStats'][user_key] ||= {} - report['usersStats'][user_key] = report['usersStats'][user_key].merge(block.call(user)) +def collect_stats_from_user + return unless @user.attributes + + stats = @user.sessions.inject({ + # Собираем количество сессий по пользователям + 'sessionsCount' => 0, + # Собираем количество времени по пользователям + 'totalTime' => 0, + # Выбираем самую длинную сессию пользователя + 'longestSession' => 0, + # Браузеры пользователя через запятую + 'browsers' => [], + # Даты сессий через запятую в обратном порядке в формате iso8601 + 'dates' => [] + }) do |metric, session| + # Собираем количество сессий по пользователям + metric['sessionsCount'] += 1 + session_time = session['time'].to_i + metric['totalTime'] += session_time + metric['longestSession'] = session_time if metric['longestSession'] < session_time + metric['browsers'] << session['browser'].upcase! + metric['dates'] << session['date'] + @result_data['allBrowsers'] << session['browser'] if !@result_data['allBrowsers'].include?(session['browser']) + metric end + + # Хоть раз использовал IE? + stats['usedIE'] = stats['browsers'].any? { |b| b =~ /INTERNET EXPLORER/ } + # Всегда использовал только Chrome? + stats['alwaysUsedChrome'] = stats['browsers'].all? { |b| b =~ /CHROME/ } + + stats['totalTime'] = "#{stats['totalTime']} min." + stats['longestSession'] = "#{stats['longestSession']} min." + stats['browsers'] = stats['browsers'].sort.join(', ') + stats['dates'].sort!.reverse! + + save_user(stats) end -def work - file_lines = File.read('data.txt').split("\n") +def save_user(stats) + @result.write(',') if @result_data['totalUsers'] > 1 - users = [] - sessions = [] + user_hash = { @user.attributes['full_name'] => stats } + json = user_hash.to_json + json = json[1...json.length - 1] if json[0] == '{' && json[-1] == '}' + @result.write(json) + @user.sessions = [] + @user.attributes = nil +end + +def work(file_name: ARGV[0] || 'data_large.txt') + @result_data = { + 'totalUsers' => 0, + 'uniqueBrowsersCount' => 0, + 'totalSessions' => 0, + 'allBrowsers' => [], + } - file_lines.each do |line| - cols = line.split(',') - users = users + [parse_user(line)] if cols[0] == 'user' - sessions = sessions + [parse_session(line)] if cols[0] == 'session' + @result = File.open('result.json', 'w') + @result.write('{"usersStats":{') + + @user = User.new(attributes: nil, sessions: []) + + File.foreach(file_name) do |line| + cols = line.chop.split(',') + case cols[0] + when 'session' + @user.sessions << parse_session(cols) + @result_data['totalSessions'] += 1 + when 'user' + collect_stats_from_user + + @user.attributes = parse_user(cols) + @result_data['totalUsers'] += 1 + end end + collect_stats_from_user + + @result_data['uniqueBrowsersCount'] = @result_data['allBrowsers'].size + @result_data['allBrowsers'] = @result_data['allBrowsers'].sort!.join(',') + + @result.write('},') + @result.write(@result_data.to_json.slice(1..-1).to_s) + @result.close + + puts 'Finish work' # Отчёт в json # - Сколько всего юзеров + # - Сколько всего уникальных браузеров + @@ -70,77 +134,7 @@ def work # - Всегда использовал только Хром? + # - даты сессий в порядке убывания через запятую + - report = {} - - report[:totalUsers] = users.count - - # Подсчёт количества уникальных браузеров - uniqueBrowsers = [] - sessions.each do |session| - browser = session['browser'] - uniqueBrowsers += [browser] if uniqueBrowsers.all? { |b| b != browser } - end - - report['uniqueBrowsersCount'] = uniqueBrowsers.count - - report['totalSessions'] = sessions.count - - report['allBrowsers'] = - sessions - .map { |s| s['browser'] } - .map { |b| b.upcase } - .sort - .uniq - .join(',') - - # Статистика по пользователям - users_objects = [] - - users.each do |user| - attributes = user - user_sessions = sessions.select { |session| session['user_id'] == user['id'] } - user_object = User.new(attributes: attributes, sessions: user_sessions) - users_objects = users_objects + [user_object] - end - - report['usersStats'] = {} - - # Собираем количество сессий по пользователям - collect_stats_from_users(report, users_objects) do |user| - { 'sessionsCount' => user.sessions.count } - end - - # Собираем количество времени по пользователям - collect_stats_from_users(report, users_objects) do |user| - { 'totalTime' => user.sessions.map {|s| s['time']}.map {|t| t.to_i}.sum.to_s + ' min.' } - end - - # Выбираем самую длинную сессию пользователя - collect_stats_from_users(report, users_objects) do |user| - { 'longestSession' => user.sessions.map {|s| s['time']}.map {|t| t.to_i}.max.to_s + ' min.' } - end - - # Браузеры пользователя через запятую - collect_stats_from_users(report, users_objects) do |user| - { 'browsers' => user.sessions.map {|s| s['browser']}.map {|b| b.upcase}.sort.join(', ') } - end - - # Хоть раз использовал IE? - collect_stats_from_users(report, users_objects) do |user| - { 'usedIE' => user.sessions.map{|s| s['browser']}.any? { |b| b.upcase =~ /INTERNET EXPLORER/ } } - end - - # Всегда использовал только Chrome? - collect_stats_from_users(report, users_objects) do |user| - { 'alwaysUsedChrome' => user.sessions.map{|s| s['browser']}.all? { |b| b.upcase =~ /CHROME/ } } - end - - # Даты сессий через запятую в обратном порядке в формате iso8601 - collect_stats_from_users(report, users_objects) do |user| - { 'dates' => user.sessions.map{|s| s['date']}.map {|d| Date.parse(d)}.sort.reverse.map { |d| d.iso8601 } } - end - File.write('result.json', "#{report.to_json}\n") puts "MEMORY USAGE: %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024) end