-
Notifications
You must be signed in to change notification settings - Fork 139
feat: make copy faster #2721
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
base: main
Are you sure you want to change the base?
feat: make copy faster #2721
Conversation
Pull Request Test Coverage Report for Build 1273Details
💛 - Coveralls |
f5b08f2
to
030cad1
Compare
030cad1
to
f86e0b6
Compare
This implementation is better than before. But there's still an unnecessary pass of initializing the array. I think it should be implemented as intrinsics from the moonc side. So I'm not sure whether we should move forward with this PR. |
f86e0b6
to
f5c60c0
Compare
Inconsistent array initialization in non-JS copy implementationCategory Missing JSArray helper functions in builtin moduleCategory Potential performance regression with make_uninit usageCategory |
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.
Pull Request Overview
Moves Array.copy into builtin array core for both non-JS and JS targets and optimizes the non-JS implementation for performance by avoiding redundant initialization.
- Add Array::copy to builtin API and implement it in arraycore_nonjs.mbt with make_uninit + unsafe_blit
- Implement Array::copy for JS in arraycore_js.mbt via JS slice(0)
- Remove prior implementations and declarations from the array package to de-duplicate
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
builtin/pkg.generated.mbti | Declares Array::copy in the builtin API surface |
builtin/arraycore_nonjs.mbt | Adds optimized non-JS implementation of Array.copy |
builtin/arraycore_js.mbt | Adds JS implementation of Array.copy using arr.slice(0) |
array/pkg.generated.mbti | Removes Array.copy declaration from array package (now provided by builtin) |
array/array_nonjs.mbt | Removes previous non-JS implementation (superseded by builtin) |
array/array_js.mbt | Removes previous JS implementation and redundant identity helpers (now in builtin) |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
/// inspect(copied, content="[1, 2, 3]") | ||
/// inspect(physical_equal(original, copied), content="false") | ||
/// ``` | ||
pub fn[T] copy(self : Array[T]) -> Array[T] { |
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.
The method is declared without the Array:: qualifier, which is inconsistent with other methods in this file (for example, Array::fill) and with the new signature exposed in builtin/pkg.generated.mbti. Define it as a method on Array to match the declared API: change the signature to:
484 |pub fn[T] Array::copy(self : Array[T]) -> Array[T] {
pub fn[T] copy(self : Array[T]) -> Array[T] { | |
pub fn[T] Array::copy(self : Array[T]) -> Array[T] { |
Copilot uses AI. Check for mistakes.
/// inspect(copied, content="[1, 2, 3]") | ||
/// inspect(physical_equal(original, copied), content="false") | ||
/// ``` | ||
pub fn[T] copy(self : Array[T]) -> Array[T] { |
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.
Same issue as the non-JS implementation: the method should be namespaced as Array::copy to match the API surface and the style used elsewhere in this file. Update the signature to:
384 |pub fn[T] Array::copy(self : Array[T]) -> Array[T] {
pub fn[T] copy(self : Array[T]) -> Array[T] { | |
pub fn[T] Array::copy(self : Array[T]) -> Array[T] { |
Copilot uses AI. Check for mistakes.
/// Creates and returns a new array with a copy of all elements from the input | ||
/// array. | ||
/// | ||
/// Parameters: | ||
/// | ||
/// * `array` : The array to be copied. | ||
/// |
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.
The documentation refers to a parameter named array, but the function uses a receiver self and has no such parameter. Please update the docs to reflect the receiver-based API (for example, remove the Parameters section or replace it with “Copies and returns a new Array from self.”).
/// Creates and returns a new array with a copy of all elements from the input | |
/// array. | |
/// | |
/// Parameters: | |
/// | |
/// * `array` : The array to be copied. | |
/// | |
/// Copies and returns a new array containing all elements from `self`. | |
/// |
Copilot uses AI. Check for mistakes.
/// Creates and returns a new array with a copy of all elements from the input | ||
/// array. | ||
/// | ||
/// Parameters: | ||
/// | ||
/// * `array` : The array to be copied. | ||
/// |
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.
Documentation mentions a parameter array, but the function is a method on Array taking self; there is no such parameter. Please align the docs with the receiver-based API (e.g., remove the Parameters section or refer to self).
/// Creates and returns a new array with a copy of all elements from the input | |
/// array. | |
/// | |
/// Parameters: | |
/// | |
/// * `array` : The array to be copied. | |
/// | |
/// Creates and returns a new array with a copy of all elements from this array. | |
/// |
Copilot uses AI. Check for mistakes.
if len == 0 { | ||
[] | ||
} else { | ||
let arr = Array::make_uninit(len) |
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.
[nitpick] Since make_uninit is used, a brief comment would help future readers understand the safety invariants for unsafe_blit (that len == self.length(), no overlap, and arr becomes fully initialized). Suggest adding a short comment above this call clarifying these guarantees.
let arr = Array::make_uninit(len) | |
let arr = Array::make_uninit(len) | |
// Safety invariants for unsafe_blit: | |
// - len == self.length() | |
// - arr is freshly allocated, so no overlap with self | |
// - arr will be fully initialized by this blit |
Copilot uses AI. Check for mistakes.
No description provided.