Welcome to today’s post.
In today’s post, I will show how to use the GPT OpenAI models to improve on source code.
Before I show how we use the GPT models to improve code, I will explain what we mean by code improvement. In an earlier post, I explained what code quality was and how we could improve it with refactoring.
In a previous post I showed how, using prompts we could generate boiler plate source code using the OpenAI GPT Generational AI models.
In the first section, I will discuss the difference between new code that a Gen AI model provides and improved code that Gen AI provides.
Difference Between Generated Code and Code Improvement
There is a difference between simply asking for new code to be generated and on a revision to existing code is that with new code. What the GPT model provides with new code snips are code that is selected from a training dataset of possible code snips that are part of working solutions in code repositories. Improvements on existing code are determined by comparing an existing code snip from a training dataset that is working and only varies by slight differences in the code being presented in the prompt.
As developers, we are writing code to build a solution to a task, we don’t consciously reproduce entire algorithms from memory. Most or the command lines are output from our knowledge of programming idioms, such as for…next loops, while loops, conditional statements etc. The other bits and pieces are obtained from libraries of useful functions available that achieves our goal, which we then we can re-use those instead of spending time re-implementing our task.
The millions of code snips that are available in a pre-trained AI model provide us with a repository on tap, which when harnessed, can give us higher levels of productivity as a developer. This provides the following benefits:
- Faster code retrieval for solutions to many tasks.
- Time saved from searching technical references on the internet.
- Learning from feedback from a pre-trained model.
In the next section, I will define what code improvement is, and what we can expect in terms of the output goals when we use the GPT AI model.
Defining Code Improvement
When we improve source code, we aim to achieve the following goals:
- Reduce bugs in the code.
- Make the code more efficient.
- Reduce the size of the code.
- Increase the code readability.
Goals 3 and 4 are part of what we call code refactoring. This involves three main tasks:
- Improve the quality of the code.
- Removing redundant lines of code without affecting the resulting logic.
- Optimizing logic to improve performance.
When we are writing code for a method or function for the first time, we are not always aware of how correct our code is unless we test it and find faults. With the assistance of an extra eye to review the code, some or maybe all the deficiencies of the code can be determined and feedback provided to the coder.
The OpenAI GPT 3.5 turbo model can provide us with responses that provide useful feedback on code generation and code improvement, much like what a pair programmer can provide us. The model can respond by providing an improved version of the code along with an explanation of what has been corrected and a summary of what the updated code does.
In some cases, we may get a response which might not be what we expect.
I will first show how we can use GPT models to identify defects and bugs in code.
GPT Model Identifies Defects and Bugs in Code
In the first example, I will show a function that is used to compute the Fibonacci function for an entered integer number. I have deliberately placed a bug in the code and named the function F so that the model searches for similarly structured code rather than by the name of named algorithm.
Below is the first prompt:
Fix bugs in the following code:
===
public int F(int n)
{
if ((n == 0) || (n == 1))
return 1;
int fiboPrev = 1;
int fiboCurr = 1;
int fiboNext = 0;
int i = 2;
while (i <= n)
{
fiboNext = fiboCurr + fiboPrev;
fiboPrev = fiboCurr;
fiboCurr = fiboNext;
i++;
}
return fiboNext + fiboCurr;
}
The model provides the following response with the corrected function implementation:
Response:
The bug in the code is in the return statement. It should only return fiboNext instead of fiboNext + fiboCurr.
Here's the corrected code:
public int F(int n)
{
if ((n == 0) || (n == 1))
return 1;
int fiboPrev = 1;
int fiboCurr = 1;
int fiboNext = 0;
int i = 2;
while (i <= n)
{
fiboNext = fiboCurr + fiboPrev;
fiboPrev = fiboCurr;
fiboCurr = fiboNext;
i++;
}
return fiboNext;
}
This code calculates the nth Fibonacci number and returns it.
A screenshot of the response is shown below:

The next example that we will submit to the GPT model for assessment has a few more bugs. Let’s have a look.
Fix bugs in the following code:
===
public int GetNthEntry(int n, int[] a)
{
int result = 0;
if (n < 0)
throw new Exception("Index is out of bounds.");
if (n > (a.Length+1))
throw new Exception("Index is out of bounds.");
for (int i=1; i<a.Length; i++)
{
int val = a[i];
if (i == n)
{
result = val;
break;
}
}
return result;
}
You can see the function is again in C#, has a few code guards to check for bounds, and a loop that searches for the target element in the array. Let’s see the response.
Here are the fixes to the code:
The loop variable i should start from 0 instead of 1, since arrays are zero-indexed.
The condition n > (a.Length+1) in the second if statement should be changed to n >= a.Length, since the maximum valid index is a.Length - 1.
The exception thrown in the first if statement should be an IndexOutOfRangeException instead of a generic Exception.
The loop should iterate until i <= a.Length instead of i < a.Length, to include the last element of the array.
The method should return result even if the loop completes without finding the nth entry.
Here is the corrected code:
public int GetNthEntry(int n, int[] a)
{
int result = 0;
if (n < 0 || n >= a.Length)
throw new IndexOutOfRangeException("Index is out of bounds.");
for (int i = 0; i <= a.Length; i++)
{
int val = a[i];
if (i == n)
{
result = val;
break;
}
}
return result;
}
These fixes address the out-of-bounds index errors and ensure that the correct nth entry is returned from the array.
A screenshot of the response is shown below:

We can see the defects and fixes here were as follows:
- The incorrect bounds [0 … n+1] that were specified in the conditional code guards were corrected to [0 … n].
- The combining of the two code guard conditions into one condition has reduced the number of commands.
- The commencing of the zero-based index in the for loop from 1 to 0.
Now that the code is correct, I will show in the next section how we are able to apply a further surprising improvement to the above code.
GPT Identifies Code Improvements through Refactoring
In this section, I will instead of getting the OpenAI GPT model to suggest bug fixes to code, I will get the Get AI GPT model to improve the code for a currently working function.
Recall the first function that we had fixed (see earlier section for details):
public int F(int n)
{
…
}
I then ask for the function to be optimized. What this means to the model is we can optimize for space and performance.
Prompt:
Can I have the code optimized.
The response is a solution which optimizes the storage of the variables that store the previous, current, and next Fibonacci number by reducing the number of retrievals and re-calculations within the for loop. Here it is:
Response:
Certainly! Here's an optimized version of the code that uses memoization to avoid redundant calculations:
public int F(int n) {
if (n <= 1)
return n;
int[] memo = new int[n + 1];
memo[0] = 0;
memo[1] = 1;
for (int i = 2; i <= n; i++) {
memo[i] = memo[i - 1] + memo[i - 2];
}
return memo[n];
}
In this version, we use an array memo to store the Fibonacci numbers calculated so far. By initializing memo[0] and memo[1] to their respective base cases, we eliminate the need for special cases in the loop. Instead of recalculating Fibonacci numbers from scratch, we use the values stored in memo to compute the next Fibonacci number.
This approach significantly reduces the number of calculations, resulting in a more efficient algorithm.
Screenshots of the response are shown below:

and

I then try asking for further code optimization. What I got was an unexpected response.
Prompt:
Can we reduce the code size further?
Response:
Yes, we can further reduce the code size by using a more compact approach called "constant space optimization."
Instead of storing the entire sequence of Fibonacci numbers in an array, we can keep track of just the last two numbers and update them as we iterate through the loop.
Here's the optimized code with reduced code size:
public int F(int n) {
if (n <= 1)
return n;
int fiboPrev = 0;
int fiboCurr = 1;
for (int i = 2; i <= n; i++) {
int fiboNext = fiboCurr + fiboPrev;
fiboPrev = fiboCurr;
fiboCurr = fiboNext;
}
return fiboCurr;
}
In this version, we use only two variables, fiboPrev and fiboCurr, to keep track of the last two Fibonacci numbers.
We update these variables in each iteration of the loop, discarding the need for an array. This approach further reduces the code size without sacrificing efficiency.
A screenshot of the response is shown below:

I had expected the previous response to perhaps be a recursive version of the function, however, what we ended up with in the response was the first function that I submitted!
To get the recursive version of the function, I submit the following prompt:
Prompt:
Can you make the code recursive?
Response:
Certainly! Here's the code for a recursive version of the Fibonacci function:
public int F(int n) {
if (n <= 1)
return n;
return F(n - 1) + F(n - 2);
}
In this recursive implementation, we handle the base cases where n is 0 or 1, and return n itself. For any other value of n, we recursively call the F function with n - 1 and n - 2, and return the sum of the results.
This recursive approach directly follows the mathematical definition of the Fibonacci sequence but may be less efficient for larger values of n due to redundant calculations.
A screenshot of the response is shown below:

The final improvement that I will show is for the second function that we had bug fixes in the previous section:
public int GetNthEntry(int n, int[] a)
{
}
Prompt:
Can I have the code improved.
Response:
Certainly! Here's an improved version of the code:
public int GetNthEntry(int n, int[] a)
{
if (n < 0 || n >= a.Length)
throw new IndexOutOfRangeException("Index is out of bounds.");
return a[n];
}
Improvements:
1. The loop has been removed since the desired nth entry can be directly accessed using the index n.
2. The code now throws an IndexOutOfRangeException directly when the index is out of bounds, avoiding the need for the first if statement.
3. The variable result has been removed since the desired nth entry can be directly returned.
This simplified code achieves the same functionality while being more concise and efficient.
A screenshot of the response is shown below:

The above code efficiency improvement has shown us that an implementation for a basic retrieval for an array element, that involved searching for the array element in a for loop (which we now know in hindsight was a bit cumbersome) could have been reduced to a one statement array reference, a[i] that directly retrieves the value from the element.
A seasoned developer could (in most cases) spot this optimization straightaway, but an inexperienced developer that wasn’t fully trained in all the nuances of the C# language would go for the longer looped approach. The OpenAI GPT model has acted as our pair programmer to spot the improvement for us and suggest the code optimization.
In the above post I have shown how to use OpenAI GPT Generative AI Chat Completion to assess segments of code, then apply the following improvements to the code:
- Determine bugs in the code. Return amended code with the rectifications applied. Provide explanation and rationale for the code fixes.
- Determine optimizations and efficiencies within the code. Return refactored amended code with optimizations. Provide explanation and rationale for the optimizations.
That is all for today’s post.
I hope that you have found this post useful and informative.
Andrew Halil is a blogger, author and software developer with expertise of many areas in the information technology industry including full-stack web and native cloud based development, test driven development and Devops.