{"id":22907439,"url":"https://github.com/oswaldobapvicjr/performetrics","last_synced_at":"2025-05-08T22:20:42.061Z","repository":{"id":44475507,"uuid":"162709816","full_name":"oswaldobapvicjr/performetrics","owner":"oswaldobapvicjr","description":"A simple performance data generator for Java applications","archived":false,"fork":false,"pushed_at":"2025-03-29T14:18:10.000Z","size":693,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-29T15:20:37.262Z","etag":null,"topics":["benchmark","counter","cpu","java","metrics-gathering","stopwatch"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oswaldobapvicjr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-21T12:07:40.000Z","updated_at":"2025-03-29T14:18:11.000Z","dependencies_parsed_at":"2024-01-28T05:28:05.178Z","dependency_job_id":"3e7f5a23-8fdc-4ec4-94b9-b3db20078129","html_url":"https://github.com/oswaldobapvicjr/performetrics","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oswaldobapvicjr%2Fperformetrics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oswaldobapvicjr%2Fperformetrics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oswaldobapvicjr%2Fperformetrics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oswaldobapvicjr%2Fperformetrics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oswaldobapvicjr","download_url":"https://codeload.github.com/oswaldobapvicjr/performetrics/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253155462,"owners_count":21862700,"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":["benchmark","counter","cpu","java","metrics-gathering","stopwatch"],"created_at":"2024-12-14T03:15:12.369Z","updated_at":"2025-05-08T22:20:42.053Z","avatar_url":"https://github.com/oswaldobapvicjr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Performetrics logo](resources/performetrics_logo.svg)\n\n[![Known Vulnerabilities](https://snyk.io/test/github/oswaldobapvicjr/performetrics/badge.svg)](https://snyk.io/test/github/oswaldobapvicjr/performetrics)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/oswaldobapvicjr/performetrics/maven.yml?branch=master)](https://github.com/oswaldobapvicjr/performetrics/actions/workflows/maven.yml)\n[![Coverage](https://img.shields.io/codecov/c/github/oswaldobapvicjr/performetrics)](https://codecov.io/gh/oswaldobapvicjr/performetrics)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.obvj/performetrics/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.obvj/performetrics)\n[![Javadoc](https://javadoc.io/badge2/net.obvj/performetrics/javadoc.svg)](https://javadoc.io/doc/net.obvj/performetrics)\n\nA simple performance data generator for Java applications\n\n---\n\n## Project overview\n\nMost Java developers use the functions `System.currentTimeMillis()` or `System.currentTimeNanos()` inside their code to measure the elapsed time to run some key operations. This is not a problem if you want to benchmark an application running in a dedicated system. However, the result is strongly affected by other activities in the system, such as background processes and I/O (e.g. disk and network activities).\n\nAs from Java 1.5, it is possible to get additional metrics that may help you benchmark a task with some most accurate units:\n\n- **Wall clock time:** the elapsed time experienced by a user waiting for a task to complete (not necessarily a bad metric if you are interested in measuring a real user experience)\n\n- **CPU time:** the total time spent using a CPU for the current thread\n\n- **User time:** the total CPU time that the current thread has executed in user mode (i.e., the time spent running the current thread's  code)\n\n- **System time:** the time spent by the OS kernel to execute all the basic/system-level operations on behalf of your application (such as context switching, resource allocation, etc.)\n\n```mermaid\n---\ndisplayMode: compact\n---\ngantt\n    title Metric types\n    dateFormat X\n    axisFormat %s\n    section Real time\n    rt1   : crit, 0, 18\n    section CPU time\n    ct1   : 0, 1\n    ct2   : 2, 3\n    ct3   : 4, 6\n    ct4   : 7, 8\n    ct5   : 9, 10\n    ct6   : 11, 13\n    ct7   : 14, 15\n    ct8   : 16, 17\n    section User time\n    ut1   : active, 0, 1\n    ut2   : active, 2, 3\n    ut3   : active, 4, 5\n    ut4   : active, 12, 13\n    section System time\n    st1   : done, 5, 6\n    st2   : done, 7, 8\n    st3   : done, 9, 10\n    st4   : done, 11, 12\n```\n\n**Performetrics** provides convenient objects for time evaluation with support to the abovementioned counters.\n\n---\n\n## How to include it\n\nIf you are using Maven, add **Performetrics** as a dependency on your pom.xml file:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003enet.obvj\u003c/groupId\u003e\n    \u003cartifactId\u003eperformetrics\u003c/artifactId\u003e\n    \u003cversion\u003e2.6.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nIf you use other dependency managers (such as Gradle, Grape, Ivy, etc.) click [here](https://maven-badges.herokuapp.com/maven-central/net.obvj/performetrics).\n\n---\n\n## How to use it\n\n### Example 1: Using the `Stopwatch` class\n\n1. Create a stopwatch and start it:\n\n    ```java\n    Stopwatch stopwatch = new Stopwatch();\n    stopwatch.start();\n    ```\n\n    \u003e **Note:** A single call `Stopwatch.createStarted()` may provide a started stopwatch for convenience.\n\n2. Execute the code to be profiled and then stop the timing session:\n\n    ```java\n    stopwatch.stop();\n    ```\n\n3. Get the elapsed time for a particular counter (e.g. CPU time), in a specific time unit:\n\n    ```java\n    double cpuTimeNanos = stopwatch.elapsedTime(Counter.Type.CPU_TIME, TimeUnit.NANOSECONDS);\n    ```\n\n    \u003e **Note:** Check the different `elapsedTime` options available to find the most suitable.\n\n4. Print the summary to the system console:\n\n    ```java\n    stopwatch.printSummary(System.out);\n    ```\n\n    \u003e **Sample output:**\n    \u003e\n    \u003e ````\n    \u003e  ====================================\n    \u003e  Counter                 Elapsed time\n    \u003e  ------------------------------------\n    \u003e  Wall clock time    0:00:01.062960500\n    \u003e  CPU time           0:00:00.109375000\n    \u003e  User time          0:00:00.046875000\n    \u003e  System time        0:00:00.062500000\n    \u003e  ====================================\n    \u003e ````\n\n    \u003e **Hint:** Call `stopwatch.printSummary(new PrintStream(\"stopwatch.csv\"), PrintStyle.SUMMARIZED_CSV)` to generate a file with stopwatch data in CSV format.\n\n5. Call `start` again to add a new timing session to the existing stopwatch.\n\n6. Print stopwatch details:\n\n    ```java\n    stopwatch.printDetails(System.out);\n    ```\n\n    \u003e **Sample output:**\n    \u003e\n    \u003e ````\n    \u003e  ===============================================\n    \u003e      #         Elapsed time     Elapsed time (+)\n    \u003e  ===============================================\n    \u003e  Wall clock time\n    \u003e  -----------------------------------------------\n    \u003e      0    0:00:01.062960500    0:00:01.062960500\n    \u003e      1    0:00:00.935263400    0:00:01.998223900\n    \u003e  -----------------------------------------------\n    \u003e  TOTAL                         0:00:01.998223900\n    \u003e  ===============================================\n    \u003e  CPU time\n    \u003e  -----------------------------------------------\n    \u003e      0    0:00:00.109375000    0:00:00.109375000\n    \u003e      1    0:00:00.140625000    0:00:00.250000000\n    \u003e  -----------------------------------------------\n    \u003e  TOTAL                         0:00:00.250000000\n    \u003e  ===============================================\n    \u003e  User time\n    \u003e  -----------------------------------------------\n    \u003e      0    0:00:00.046875000    0:00:00.046875000\n    \u003e      1    0:00:00.062500000    0:00:00.109375000\n    \u003e  -----------------------------------------------\n    \u003e  TOTAL                         0:00:00.109375000\n    \u003e  ===============================================\n    \u003e ````\n\n---\n\n### Example 2: Using the `MonitoredRunnable`\n\nIn this example, we use `Performetrics.monitorOperation(...)` to run a procedure represented by a lambda expression and print the elapsed **wall-clock** and **CPU time** at the system console.\n\n1. Create a monitored runnable, with the the procedure to be executed attached:\n\n    ```java\n    MonitoredRunnable operation = Performetrics.monitorOperation(() -\u003e myObject.doStuff());\n    ```\n\n2. Print the elapsed time for each counter:\n\n    ```java\n    System.out.println(operation.elapsedTime(Counter.Type.WALL_CLOCK_TIME));\n    System.out.println(operation.elapsedTime(Counter.Type.USER_TIME));\n    ```\n    \u003e **Sample output:**\n    \u003e\n    \u003e ````\n    \u003e 1.4208931 second(s)\n    \u003e 0.0156250 second(s)\n    \u003e ````\n\n3. Print the summary in Linux style:\n\n    ```java\n    operation.printSummary(System.out, PrintSyle.LINUX));\n    ```\n    \u003e **Sample output:**\n    \u003e\n    \u003e ````\n    \u003e real    0m1.420s\n    \u003e user    0m0.015s\n    \u003e sys     0m0.000s\n    \u003e ````\n\n\n---\n\n### Example 3: Working with Durations\n\nThe objects from the package `net.obvj.performetrics.util` contain useful features for parsing, conversion, formatting, and working with time durations. See some examples below:\n\n1. Create a collection of time durations (or obtain some using `Stopwatch.elapsedTime()`):\n\n    ```java\n    Duration duration1 = Duration.of(1, TimeUnit.SECONDS);\n    Duration duration2 = Duration.of(500, TimeUnit.MILLISECONDS);\n    List\u003cDuration\u003e durations = Arrays.asList(duration1, duration2);\n    ```\n\n2. Discover the average duration:\n\n    ```java\n    Duration average = DurationUtils.average(durations);\n    System.out.println(average); //result: 0.75 second(s)\n    ```\n\n2. Discover the lowest and highest durations and convert them to seconds:\n\n    ```java\n    double min = DurationUtils.min(durations).toSeconds(); //result: 0.5\n    double max = DurationUtils.max(durations).toSeconds(); //result: 1.0\n    ```\n\n---\n    \n## Configuration\n\n**Performetrics** does not only collect valuable metrics. A comprehensive set of features was carefully designed to optimize data collection and present the results in different styles requiring a minimum of code.\n\n### Conversion Modes\n\nPerformetrics provides two different conversion modes that can be applied depending on the user's requirements.\n\n* **Fast conversion**: uses Java-standard classes to convert durations to different time units. Although conversions in this mode are extremely fast, those from finer to coarser granularities truncate, so lose precision. For example, converting 999 milliseconds to seconds results in 0 (worst case).\n\n  To set this mode, call `Performetrics.configuration().setDefaultConversionMode(ConversionMode.FAST)`.  \n\n* **Double-precision (default)**: implements a more robust conversion logic that avoids truncation from finer to coarser granularity. For example, converting 999 milliseconds to seconds results in 0.999\n\n  An initial precision of 9 decimal places is set by default. This property can be changed calling `Performetrics.configuration().setScale(int)`.\n\n\u003e **Note:** Check the  **[Javadoc](https://javadoc.io/doc/net.obvj/performetrics)** to find out how to specify a different conversion mode for a single operation.\n\n---\n\n## Architecture\n\nThe following picture represents the main classes and their relationships. Click [here](resources/Detailed%20class%20diagram%20-%20v2.2-B.svg) for a detailed diagram.\n\n```mermaid\nflowchart LR\n  S[fa:fa-stopwatch Stopwatch]:::yellow\n  T[fa:fa-bars-progress TimingSession]:::yellow\n  CT[\"fa:fa-flag CounterType\"]:::blue\n  C[fa:fa-spinner Counter]:::yellow\n  D[fa:fa-hourglass-half Duration]\n  CM[fa:fa-arrow-up-right-from-square ConversionMode]:::blue\n  DF[fa:fa-italic DurationFormat]:::blue\n  SU[fa:fa-gears SystemUtils]:::green\n\n  S --\u003e|create/start| T\n  T --\u003e|contain| C\n  C --\u003e|defined by| CT\n  C --\u003e|produce| D\n  C --\u003e|apply| CM\n  D --\u003e|formatted by| DF\n  CT --\u003e|gather from| SU\n\n  classDef yellow stroke:#fa0\n  classDef blue stroke:#0af\n  classDef green stroke:#0fa\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foswaldobapvicjr%2Fperformetrics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foswaldobapvicjr%2Fperformetrics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foswaldobapvicjr%2Fperformetrics/lists"}