{"id":18700913,"url":"https://github.com/rabestro/forward-or-backward","last_synced_at":"2025-11-08T22:30:42.916Z","repository":{"id":184818730,"uuid":"672525171","full_name":"rabestro/forward-or-backward","owner":"rabestro","description":"This project aims to show how expensive extra function calls can be when defining a loop boundary. ","archived":false,"fork":false,"pushed_at":"2023-07-31T07:09:46.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-28T05:25:20.126Z","etag":null,"topics":["backward","boundary","comparison","for-loop","forward","jmh-benchmarks","loops-and-iterations"],"latest_commit_sha":null,"homepage":"","language":"Java","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/rabestro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-30T11:37:39.000Z","updated_at":"2023-07-31T06:38:22.000Z","dependencies_parsed_at":"2023-07-31T08:47:26.001Z","dependency_job_id":null,"html_url":"https://github.com/rabestro/forward-or-backward","commit_stats":null,"previous_names":["rabestro/forward-or-backward-for-loops","rabestro/forward-or-backward"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabestro%2Fforward-or-backward","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabestro%2Fforward-or-backward/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabestro%2Fforward-or-backward/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabestro%2Fforward-or-backward/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rabestro","download_url":"https://codeload.github.com/rabestro/forward-or-backward/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239565650,"owners_count":19660154,"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":["backward","boundary","comparison","for-loop","forward","jmh-benchmarks","loops-and-iterations"],"created_at":"2024-11-07T11:39:46.318Z","updated_at":"2025-11-08T22:30:42.880Z","avatar_url":"https://github.com/rabestro.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Forward or Backward? \n\nThis project aims to show how expensive extra function calls can be when defining a loop boundary.\n\n## Description\n\nIn this example, we use the number of names in the path as the loop boundary. \nWe can either start at the beginning of the path and work forward or at the end and work backward. \nThe results show that working backward in a particular case is six times faster than working forward.\nThe reason for this is that in the first case, we call the method `Path::getNameCount` on every iteration of the loop, whereas in the last case, we call this function once at the beginning of the circle.\n\nThis example shows how important it is to calculate loop boundaries in advance.\n\n## Methods to be benchmarked\n\n```java\npublic class MyBenchmark {\n    private static final Path SAMPLE_PATH = Path.of(\"/home/user/projects/dict/src/main/resources/words.txt\");\n\n    @Benchmark\n    public int forwardLoop() {\n        var count = 0;\n        // calculate loop boundaries at each iteration\n        for (\n                var i = 0;\n                i \u003c SAMPLE_PATH.getNameCount();\n                i++\n        ) {\n            count++;\n        }\n        return count;\n    }\n\n    @Benchmark\n    public int reverseLoop() {\n        var count = 0;\n        // calculate loop boundaries once at the very beginning\n        for (\n                var i = SAMPLE_PATH.getNameCount();\n                i \u003e 0;\n                i--\n        ) {\n            count++;\n        }\n        return count;\n    }\n}\n```\n\n\n## Running the benchmark\n\nTo execute the benchmark, access your project folder through the command line and execute the following command.\n```shell\nmvn clean verify\n```\nThis action will generate the `target` folder within your project, housing the benchmarks Uber-JAR file that you'll utilize.\nNext, proceed by running the following command from the same location.\n```shell\njava -jar target/benchmarks.jar\n```\nOnce all benchmarks conclude, you'll receive the following completion message.\n\n```text\nBenchmark                 Mode  Cnt          Score         Error  Units\nMyBenchmark.forwardLoop  thrpt   25   86563253.402 ±  198686.009  ops/s\nMyBenchmark.reverseLoop  thrpt   25  517055621.588 ± 2150399.471  ops/s\n```\n\nI added a simple graph to represent digital data better.\n\n![graph chart](https://docs.google.com/spreadsheets/d/e/2PACX-1vROjoNO8NJuXRnyfNje9XnU-YhXEsEzxD1lIzXU2LYVekUK2fYCg2JxkaUhoyi77Ust-EvJ4d5LppJ6/pubchart?oid=1966749143\u0026format=image)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frabestro%2Fforward-or-backward","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frabestro%2Fforward-or-backward","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frabestro%2Fforward-or-backward/lists"}