--- title: "Jam 02 - Exercise 2 - Measuring Performance Impact" tags: - 3 ๐Ÿงช in testing - 4 ๐Ÿฅณ done - jam02 - types - objects - performance --- <!-- markdownlint-disable line-length single-h1 no-inline-html --> <!-- markdownlint-configure-file { "ul-indent": { "indent": 4 }, "link-fragments": {"ignore_case": true} } --> # Exercise 2 - Measuring Performance Impact {%hackmd dJZ5TulxSDKme-3fSY4Lbw %} ## Overview - Exercise 2 Let's put our understanding to the test with a hands-on experiment that will demonstrate the performance difference between primitive types and wrapper classes. We'll create a simple program that performs the same calculation using both approaches and measure the time difference. ## Required Steps - Performance Experiment 1. First, create a new file called `PrimitivePerf.java` in your `jam02` directory. Here's the starter code: ```java= /** * A simple experiment to help you understand the impact of * your design choices on even the simplest of concepts โ€“ using * primitive types vs. objects. */ public class PrimitivePerf { /** The quantity of numbers to compute a sum for */ private static final int MAX_NUMBERS = 10000000; /** MAIN PROGRAM */ public static void main(String[] args) { // Our time durations we will use to store our results long primitiveDuration = 0L; long wrappedDuration = 0L; // Evaluate the test with primitive types long primitiveResult = testPrimitive(); // Now, evaluate the test with the wrapper class type Long wrappedResult = testWrapped(); // TODO - Print results, timing, and pct difference between times } /** * Simple function to evaluate the speed of adding numbers that are * primitive types */ public static long testPrimitive() { // Store the result as a primitive type long sum = 0L; for (int i = 0; i < MAX_NUMBERS; i++) { sum = sum + i; } return sum; } /** * Simple function to evaluate the speed of adding numbers that are stored * as an object. */ public static Long testWrapped() { // Store the result as an object Long, not the primitive type! Long objSum = 0L; for (int i = 0; i < MAX_NUMBERS; i++) { objSum = objSum + i; } return objSum; } } ``` 2. Make sure you have `PrimitivePerf.java` open in IntelliJ. In simplest terms, it's job is to run two tests that sum numbers from 1 to `MAX_NUMBERS` and then report the results. The class contains: - One data member: A constant `MAX_NUMBERS` set to 10,000,000 that indicates the number of numbers to sum - A partially complete `main` method that runs the experiment - Two static methods: - `testPrimitive()` using the primitive type `long` - `testWrapped()` using the wrapper class `Long` - The `main` method is partially complete and you need to complete it. 3. Look closely at the subtle but important difference between the two methods (remember programming languages are case sensitive!): ```java= // testPrimitive uses a primitive long long sum = 0L; // testWrapped uses a wrapper Long Long objSum = 0L; ``` 4. To measure the performance difference, we'll use `System.nanoTime()`. Look this up in the Java 21 API documentation (remember what you learned about the API in Jam01!). :::info ๐Ÿ”‘ **Measuring Time with nanoTime()** Here's an example from the API documentation showing how to measure elapsed time: ```java long startTime = System.nanoTime(); // ... the code being measured ... long elapsedNanos = System.nanoTime() - startTime; ``` How would we use this? 1. Capture the start time 2. Call the test method (`testPrimitive()` or `testWrapped()`) 3. Capture the end time 4. Calculate the elapsed time by subtracting start from end ::: 5. Complete the `main` method to: - Capture the time before and after each test - Calculate and display the elapsed time for each method - Compare the results Your output should look like this: ```text Primitive: Answer = 49999995000000. Time = XXX ns Wrapped: Answer = 49999995000000. Time = XXX ns Primitive types used XX.X% of the time of wrapper objects. ``` :::warning ๐Ÿšง **Important Notes** - Both methods will give the same mathematical result - The timing difference is what we're interested in - Make sure to update the banner comment at the top of the file with your information ::: >[!Important] Questions for answers.txt > >(2.1) Copy and paste your program's output. > >(2.2) Reflect on your results. Why do you think you observed such a timing difference between the two types? Think about what Java has to do behind the scenes with wrapper objects vs primitive types. <!-- Comment to split quote boxes --> > ๐Ÿ” **Checkpoint**: Before moving on, verify: > > - Your `PrimitivePerf.java` file compiles and runs without errors > - You've successfully measured and compared performance between primitive and wrapper types > - Your output matches the expected format > - You've documented your findings in `answers.txt` for questions 2.1-2.2 > - Your working directory is clean (no uncommitted changes) ## Save Your Work - Exercise 2 Verify what files are uncommited: ```bash git status ``` Stage your changes (This should be the file shown in `git status` as modified) Feel free to use a different message as long as it's descriptive ```bash git add src/main/java/jam02/PrimitivePerf.java src/main/java/jam02/answers.txt ``` Commit your work ```bash git commit -m "jam02: Complete performance comparison experiment" ``` Your working directory should be now be clean.