-
Notifications
You must be signed in to change notification settings - Fork 2.9k
perf(llm): Optimize pruneLines functions in countTokens #5310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ Deploy Preview for continuedev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a fairly complex change that affects a lot of things, so if we are going to consider merging this I would ask that it come with very good testing. Are you able to add unit tests that cover edge cases and make sure that this hasn't regressed in any way?
@0x23d11 There are some tests in countTokens.test.ts that you could just flesh out a bit with more examples and then unskip! |
@RomneyDa ok I've seen the tests, I'll write some more examples for the tests. After that it should be good to go right? Considering all the new test additions are good enough |
@0x23d11 I'd love to merge this PR, please let me know if you have the chance to write some tests, or if you'd like any help! |
Just wanted to bump this. I'm happy to leave it open for a while, but tests are important here since it's a very core piece of logic, and relatively complex |
Hey @0x23d11, let me know if you have chance to look at this PR again. I'm probably going to close it if it becomes stale for longer. At this point just waiting on tests |
Hi @sestinj sorry for the delay, I'll add the tests by this weekend |
@0x23d11 just wanted to bump this again. Let me know if you need any help |
All contributors have signed the CLA ✍️ ✅ |
I have read the CLA Document and I hereby sign the CLA |
@sestinj please take a look, I've added the tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for adding the tests, this looks great!
Description
Closes #4947
This PR addresses issue #4947 by optimizing the performance of the
pruneLinesFromTop
andpruneLinesFromBottom
functions incore/llm/countTokens.ts
Problem
The previous implementations used
Array.prototype.shift()
andArray.prototype.pop()
within awhile
loop to remove lines from the beginning or end of a prompt until it fit within the token limit. These array modification methods have a time complexity of O(n) because they require shifting subsequent elements. When dealing with very long prompts (e.g., thousands of lines), repeatedly callingshift()
orpop()
becomes computationally expensive, leading to significant performance degradation.Solution
The implemented solution refactors these functions to avoid costly array modifications within the loop:
lineTokens
).lineTokens
and adding the count for necessary newline characters (\n
).while
loop iterates as long as thetotalTokens
exceedsmaxTokens
.lines
array, an index pointer (start
orend
) is adjusted.totalTokens
.Array.prototype.slice()
(an O(n) operation performed only once) is used with the finalstart
orend
index to extract the desired lines.Benefits
This approach drastically reduces the computational complexity, especially for large prompts, as the expensive O(n) operations (
shift
/pop
) inside the loop are replaced by cheap O(1) index increments/decrements. The token calculation per line and the finalslice
operation are performed only once.Checklist
Screenshots
[ For visual changes, include screenshots. Screen recordings are particularly helpful, and appreciated! ]
Testing instructions
Objective:
The primary goal of this PR is to optimize the performance of the pruneLinesFromTop and pruneLinesFromBottom utility functions. These functions are responsible for truncating a given string (prompt) by removing lines from the top or bottom, respectively, to ensure the resulting string does not exceed a specified maxTokens limit when processed by an LLM. This testing aims to verify that the optimized functions:
Correctly prune lines to meet the maxTokens constraint.
Maintain the existing logical behavior (i.e., correctly choose which lines to remove and which to keep).
Handle various edge cases appropriately.
Instructions:
The most direct way to test these changes is by running the unit tests specifically written for these functions. We've recently added comprehensive tests for various scenarios.
Prerequisites: Ensure your development environment is set up and you can run tests.
Execution:
Navigate to the root directory of the continue project in your terminal.
Run the following command to execute the test suite for countTokens.ts:
Expected Results:
These tests cover: