{"id":13878842,"url":"https://github.com/testdouble/time_up","last_synced_at":"2025-07-16T14:33:05.904Z","repository":{"id":56897025,"uuid":"386364013","full_name":"testdouble/time_up","owner":"testdouble","description":"⏱ Create and manage multiple timers to tell where your Ruby code's time is going","archived":false,"fork":false,"pushed_at":"2023-09-26T11:28:23.000Z","size":38,"stargazers_count":117,"open_issues_count":1,"forks_count":1,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-08-09T06:54:51.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/testdouble.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-07-15T16:56:48.000Z","updated_at":"2023-09-26T11:23:12.000Z","dependencies_parsed_at":"2024-01-13T20:45:38.653Z","dependency_job_id":"a416b961-a4e8-4ab8-b969-c1a336ef05e0","html_url":"https://github.com/testdouble/time_up","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testdouble%2Ftime_up","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testdouble%2Ftime_up/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testdouble%2Ftime_up/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testdouble%2Ftime_up/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/testdouble","download_url":"https://codeload.github.com/testdouble/time_up/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226138849,"owners_count":17579496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T08:02:01.695Z","updated_at":"2024-11-24T07:31:21.514Z","avatar_url":"https://github.com/testdouble.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# time_up\n\nEver need to measure the elapsed wall-time for one or more bits of Ruby code,\nbut don't necessarily want to reach for\n[Benchmark](https://ruby-doc.org/stdlib-3.0.1/libdoc/benchmark/rdoc/Benchmark.html) or roll your own ad hoc measurement code?\nTry `time_up`!\n\nThis gem is especially useful for long-running processes (like test suites) that\nhave several time-intensive operations that are repeated over the life of the\nprocess and that you want to measure in aggregate. (For example, to see how\nmuch time your test suite spends creating factories, truncating the database, or\ninvoking a critical code path.)\n\nHere's a [blog post about time_up](https://blog.testdouble.com/posts/2021-07-19-benchmarking-your-ruby-with-time_up/) and \na [great example of when it can be useful](https://gist.github.com/searls/feee0b0eac7c329b390fed90c4714afb).\n\n## Install\n\nJust run `gem install time_up` or add time_up to your Gemfile:\n\n```ruby\ngem \"time_up\"\n```\n\n## Usage\n\nStarting a timer is easy! Just call `TimeUp.start`:\n\n```ruby\n# Pass a block and time_up will only count the time while the block executes:\nTimeUp.start(:factories) do\n  # … create some factories\nend\n\n# Without a block, a started timer will run until you stop it:\nTimeUp.start(:truncation)\n# … truncate some stuff\nTimeUp.stop(:truncation)\n```\n\nTo get the total time that's elapsed while the timer has been running, call\n`elapsed`:\n\n```ruby\nslow_time = TimeUp.elapsed(:slow_code_path)\n```\n\nWhich will return a `Float` representing the number of seconds that have elapsed\nwhile the timer is running.\n\nTimers aggregate total elapsed time running, just like a digital stopwatch. That\nmeans if you start a timer after it's been stopped, the additional time will be\n_added_ to the previous elapsed time:\n\n```ruby\nTimeUp.start :eggs\nsleep 1\nputs TimeUp.stop :eggs # =\u003e ~1.0\n\nTimeUp.start :eggs\nsleep 1\n# To get the elapsed time without necessarily stopping the timer, call `elapsed`\nputs TimeUp.elapsed :eggs # =\u003e ~2.0\n\n# To reset a timer to 0, call `reset` (if it's running, it'll keep running!)\nTimeUp.reset :eggs\nsleep 5\nputs TimeUp.stop :eggs # =\u003e ~5.0\n```\n\nWhen passes without a block, `TimeUp.start` returns an instance of the timer,\nwhich has its own `start`, `stop`, `elaped`, and `reset` methods. If you want to\nfind that instance later, you can also call `TimeUp.timer(:some_name)`. So the\nabove example could be rewritten as:\n\n```ruby\negg_timer = TimeUp.start :eggs\nsleep 1\nputs egg_timer.stop # =\u003e ~1.0\n\negg_timer.start\nsleep 1\n\n# To get the elapsed time without necessarily stopping the timer, call `elapsed`\nputs egg_timer.elapsed # =\u003e ~2.0\n\n# To reset a timer to 0, call `reset` (if it's running, it'll keep running!)\negg_timer.reset\nsleep 5\nputs egg_timer.stop # =\u003e ~5.0\n```\n\nFinally, if you're juggling a bunch of timers, you can get a summary report of\nthem printed for you, like so:\n\n```ruby\nTimeUp.start :roast\nsleep 0.03\nTimeUp.start :veggies\nsleep 0.02\nTimeUp.start :pasta\nsleep 0.01\nTimeUp.stop_all\n\nTimeUp.start :souffle\n\nTimeUp.print_summary\n```\n\nWhich will output something like:\n\n```\nTimeUp summary\n========================\n:roast   \t0.07267s\n:veggies \t0.03760s\n:pasta   \t0.01257s\n:souffle*\t0.00003s\n\n* Denotes that the timer is still active\n```\n\nAnd if you're calling the timers multiple times and want to see some basic\nstatistics in the print-out, you can call `TimeUp.print_detailed_summary`, which\nwill produce this:\n\n```\n=============================================================================\n  Name    | Elapsed | Count |   Min   |   Max   |  Mean   | Median  | 95th %\n-----------------------------------------------------------------------------\n:roast    | 0.08454 | 3     | 0.00128 | 0.07280 | 0.02818 | 0.01046 | 0.06657\n:veggies  | 0.03779 | 1     | 0.03779 | 0.03779 | 0.03779 | 0.03779 | 0.03779\n:pasta    | 0.01260 | 11    | 0.00000 | 0.01258 | 0.00115 | 0.00000 | 0.00630\n:souffle* | 0.00024 | 1     | 0.00024 | 0.00025 | 0.00025 | 0.00025 | 0.00026\n\n* Denotes that the timer is still active\n```\n\n## API\n\nThis gem defines a bunch of public methods but they're all pretty short and\nstraightforward, so when in doubt, I'd encourage you to [read the\ncode](/lib/time_up.rb).\n\n### `TimeUp` module\n\n`TimeUp.timer(name)` - Returns the `Timer` instance named `name` (creating it,\nif it doesn't exist)\n\n`TimeUp.start(name, [\u0026blk])` - Starts (or restarts) a named\n[Timer](#timeuptimer-class). If passed a block, will return whatever the block\nevaluates to. If called without a block, it will return the timer object\n\n`TimeUp.stop(name)` - Stops the named timer\n\n`TimeUp.reset(name)` - Resets the named timer's elapsed time to 0, effectively\nrestarting it if it's currently running\n\n`TimeUp.elapsed(name)` - Returns a `Float` of the total elapsed seconds that the\nnamed timer has been running\n\n`TimeUp.timings(name)` - Returns an array of each recorded start-to-stop\nduration (including the current one, if the timer is running) of the named timer\n\n`TimeUp.count(name)` - The number of times the timer has been started (including\nthe current timing, if the timer is running)\n\n`TimeUp.min(name)` - The shortest recording by the timer\n\n`TimeUp.max(name)` - The longest recording by the timer\n\n`TimeUp.mean(name)` - The arithmetic mean of all recordings by the timer\n\n`TimeUp.median(name)` - The median of all recordings by the timer\n\n`TimeUp.percentile(name, percent)` - The timing for the given\n[percentile](https://en.wikipedia.org/wiki/Percentile) of all recordings by the\ntimer\n\n`TimeUp.total_elapsed` - Returns a `Float` of the sum of `elapsed` across all\nthe timers you've created (note that because you can easily run multiple logical\ntimers simultaneously, this figure may exceed the total time spent by the\ncomputer)\n\n`TimeUp.all_elapsed` - Returns a Hash of timer name keys mapped to their\n`elapsed` values. Handy for grabbing a reference to a snapshot of the state of\nthings without requiring you to stop your timers\n\n`TimeUp.all_stats` - Returns a Hash of timer name keys mapped to another\nhash of their basic statistics (`elapsed`, `count`, `min`, `max`,\nand `mean`)\n\n`TimeUp.active_timers` - Returns an Array of all timers that are currently\nrunning. Useful for detecting cases where you might be keeping time in multiple\nplaces simultaneously\n\n`TimeUp.print_summary([io])` - Pretty-prints a multi-line summary of all your\ntimers' total elapsed times to standard output (or the provided\n[IO](https://ruby-doc.org/core-3.0.1/IO.html))\n\n`TimeUp.print_detailed_summary([io])` - Pretty-prints a multi-line summary of\nall your timers' elapsed times and basic statistics to standard output (or the\nprovided [IO](https://ruby-doc.org/core-3.0.1/IO.html))\n\n`TimeUp.stop_all` - Stops all timers\n\n`TimeUp.reset_all` - Resets all timers\n\n`TimeUp.delete_all` - Stops and resets all timers and deletes any internal\nreference to them\n\n### `TimeUp::Timer` class\n\n`start` - Starts the timer\n\n`stop` - Stops the timer\n\n`elapsed` - A `Float` of the total elapsed seconds the timer has been running\n\n`timings` - Returns an Array of each recorded start-to-stop duration of the\ntimer (including the current one, if the timer is running)\n\n`count` - The number of times the timer has been started and stopped\n\n`min` - The shortest recording of the timer\n\n`max` - The longest recording of the timer\n\n`mean` - The arithmetic mean of all recorded durations of the timer\n\n`median(name)` - The median of all recordings by the timer\n\n`percentile(name, percent)` - The timing for the given\n[percentile](https://en.wikipedia.org/wiki/Percentile) of all recordings by the\ntimer\n\n`active?` - Returns `true` if the timer is running\n\n`reset(force: false)` - Resets the timer to 0 elapsed seconds. If `force` is\ntrue, will also stop the timer if it's running\n\n## Code of Conduct\n\nThis project follows Test Double's [code of\nconduct](https://testdouble.com/code-of-conduct) for all community interactions,\nincluding (but not limited to) one-on-one communications, public posts/comments,\ncode reviews, pull requests, and GitHub issues. If violations occur, Test Double\nwill take any action they deem appropriate for the infraction, up to and\nincluding blocking a user from the organization's repositories.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftestdouble%2Ftime_up","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftestdouble%2Ftime_up","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftestdouble%2Ftime_up/lists"}