From f5c60c0b78c986ad71dd24fbbb0ed1ba20c6d248 Mon Sep 17 00:00:00 2001 From: zihang Date: Thu, 11 Sep 2025 15:11:45 +0800 Subject: [PATCH] feat: make copy faster --- array/array_js.mbt | 28 ---------------------------- array/array_nonjs.mbt | 29 ----------------------------- array/pkg.generated.mbti | 1 - builtin/arraycore_js.mbt | 26 ++++++++++++++++++++++++++ builtin/arraycore_nonjs.mbt | 29 +++++++++++++++++++++++++++++ builtin/pkg.generated.mbti | 1 + 6 files changed, 56 insertions(+), 58 deletions(-) diff --git a/array/array_js.mbt b/array/array_js.mbt index 736496b1b..0e980e7ae 100644 --- a/array/array_js.mbt +++ b/array/array_js.mbt @@ -15,12 +15,6 @@ ///| priv type JSArray -///| -fn[T] JSArray::ofAnyArray(array : Array[T]) -> JSArray = "%identity" - -///| -fn[T] JSArray::toAnyArray(self : JSArray) -> Array[T] = "%identity" - ///| fn[T] JSArray::ofAnyFixedArray(array : FixedArray[T]) -> JSArray = "%identity" @@ -30,25 +24,3 @@ fn[T] JSArray::toAnyFixedArray(self : JSArray) -> FixedArray[T] = "%identity" ///| extern "js" fn JSArray::copy(self : JSArray) -> JSArray = #|(arr) => arr.slice(0) - -///| -/// Creates and returns a new array with a copy of all elements from the input -/// array. -/// -/// Parameters: -/// -/// * `array` : The array to be copied. -/// -/// Returns a new array containing all elements from the original array. -/// -/// Example: -/// -/// ```moonbit -/// let original = [1, 2, 3] -/// let copied = original.copy() -/// inspect(copied, content="[1, 2, 3]") -/// inspect(physical_equal(original, copied), content="false") -/// ``` -pub fn[T] copy(self : Array[T]) -> Array[T] { - JSArray::ofAnyArray(self).copy().toAnyArray() -} diff --git a/array/array_nonjs.mbt b/array/array_nonjs.mbt index b4964a71b..4e36a8aa8 100644 --- a/array/array_nonjs.mbt +++ b/array/array_nonjs.mbt @@ -11,32 +11,3 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - -///| -/// Creates and returns a new array with a copy of all elements from the input -/// array. -/// -/// Parameters: -/// -/// * `array` : The array to be copied. -/// -/// Returns a new array containing all elements from the original array. -/// -/// Example: -/// -/// ```moonbit -/// let original = [1, 2, 3] -/// let copied = original.copy() -/// inspect(copied, content="[1, 2, 3]") -/// inspect(physical_equal(original, copied), content="false") -/// ``` -pub fn[T] copy(self : Array[T]) -> Array[T] { - let len = self.length() - if len == 0 { - [] - } else { - let arr = Array::make(len, self[0]) - Array::unsafe_blit(arr, 0, self, 0, len) - arr - } -} diff --git a/array/pkg.generated.mbti b/array/pkg.generated.mbti index 0b3639c93..89f5aba69 100644 --- a/array/pkg.generated.mbti +++ b/array/pkg.generated.mbti @@ -49,7 +49,6 @@ impl[T : Eq] Eq for FixedArray[T] impl[T : Hash] Hash for FixedArray[T] impl[X : @quickcheck.Arbitrary] @quickcheck.Arbitrary for FixedArray[X] -fn[T] Array::copy(Self[T]) -> Self[T] fn[A, B] Array::filter_map(Self[A], (A) -> B? raise?) -> Self[B] raise? fn[T] Array::from_iter(Iter[T]) -> Self[T] fn[A : @string.ToStringView] Array::join(Self[A], StringView) -> String diff --git a/builtin/arraycore_js.mbt b/builtin/arraycore_js.mbt index 3f2fbdcbe..3bf6e92ca 100644 --- a/builtin/arraycore_js.mbt +++ b/builtin/arraycore_js.mbt @@ -358,3 +358,29 @@ pub fn[A] Array::fill( } JSArray::ofAnyArray(self).fill(JSValue::ofAny(value), start, end) } + +///| +extern "js" fn JSArray::copy(self : JSArray) -> JSArray = + #|(arr) => arr.slice(0) + +///| +/// Creates and returns a new array with a copy of all elements from the input +/// array. +/// +/// Parameters: +/// +/// * `array` : The array to be copied. +/// +/// Returns a new array containing all elements from the original array. +/// +/// Example: +/// +/// ```moonbit +/// let original = [1, 2, 3] +/// let copied = original.copy() +/// inspect(copied, content="[1, 2, 3]") +/// inspect(physical_equal(original, copied), content="false") +/// ``` +pub fn[T] copy(self : Array[T]) -> Array[T] { + JSArray::ofAnyArray(self).copy().toAnyArray() +} diff --git a/builtin/arraycore_nonjs.mbt b/builtin/arraycore_nonjs.mbt index 772a9904f..fd5cdcb28 100644 --- a/builtin/arraycore_nonjs.mbt +++ b/builtin/arraycore_nonjs.mbt @@ -462,3 +462,32 @@ pub fn[A] Array::fill( } self.buf.unchecked_fill(start, value, length - start) } + +///| +/// Creates and returns a new array with a copy of all elements from the input +/// array. +/// +/// Parameters: +/// +/// * `array` : The array to be copied. +/// +/// Returns a new array containing all elements from the original array. +/// +/// Example: +/// +/// ```moonbit +/// let original = [1, 2, 3] +/// let copied = original.copy() +/// inspect(copied, content="[1, 2, 3]") +/// inspect(physical_equal(original, copied), content="false") +/// ``` +pub fn[T] copy(self : Array[T]) -> Array[T] { + let len = self.length() + if len == 0 { + [] + } else { + let arr = Array::make_uninit(len) + Array::unsafe_blit(arr, 0, self, 0, len) + arr + } +} diff --git a/builtin/pkg.generated.mbti b/builtin/pkg.generated.mbti index c22ab52cf..0f1c7fd55 100644 --- a/builtin/pkg.generated.mbti +++ b/builtin/pkg.generated.mbti @@ -80,6 +80,7 @@ fn[T] Array::chunk_by(Self[T], (T, T) -> Bool raise?) -> Self[Self[T]] raise? fn[T] Array::chunks(Self[T], Int) -> Self[Self[T]] fn[T] Array::clear(Self[T]) -> Unit fn[T : Eq] Array::contains(Self[T], T) -> Bool +fn[T] Array::copy(Self[T]) -> Self[T] fn[T : Eq] Array::dedup(Self[T]) -> Unit fn[T] Array::drain(Self[T], Int, Int) -> Self[T] fn[T] Array::each(Self[T], (T) -> Unit raise?) -> Unit raise?