Optimise Number.parseInt

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7XSO8

Change-Id: I9947a357b4a83277e618b1834a11c27afc87aa46
Signed-off-by: zhixinaa <1696730989@qq.com>
This commit is contained in:
zhixinaa 2023-09-18 09:10:23 +08:00
parent b9602b10f4
commit 80beec904c
10 changed files with 207 additions and 14 deletions

View File

@ -196,6 +196,12 @@ JSTaggedValue BuiltinsNumber::ParseInt(EcmaRuntimeCallInfo *argv)
// 1. Let inputString be ToString(string).
JSHandle<EcmaString> numberString = JSTaggedValue::ToString(thread, msg);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
if ((radix == base::DECIMAL || radix == 0)) {
int32_t elementIndex = 0;
if (EcmaStringAccessor(numberString).ToInt(&elementIndex)) {
return GetTaggedInt(elementIndex);
}
}
CVector<uint8_t> buf;
Span<const uint8_t> str = EcmaStringAccessor(numberString).ToUtf8Span(buf);

View File

@ -696,24 +696,64 @@ bool EcmaString::ToElementIndex(uint32_t *index)
*index = 0;
return len == 1;
}
if (c > '0' && c <= '9') {
n = c - '0';
for (uint32_t i = 1; i < len; i++) {
c = data[i]; // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (c < '0' || c > '9') {
return false;
}
// NOLINTNEXTLINE(readability-magic-numbers)
n = n * 10 + (c - '0'); // 10: decimal factor
}
if (n < JSObject::MAX_ELEMENT_INDEX) {
*index = n;
return true;
}
uint32_t loopStart = 0;
if (ToUInt64FromLoopStart(&n, loopStart, data) && n < JSObject::MAX_ELEMENT_INDEX) {
*index = n;
return true;
}
return false;
}
bool EcmaString::ToInt(int32_t *index)
{
uint32_t len = GetLength();
if (UNLIKELY(len == 0 || len > MAX_ELEMENT_INDEX_LEN)) { // NOLINTNEXTLINEreadability-magic-numbers)
return false;
}
if (UNLIKELY(IsUtf16())) {
return false;
}
bool negative = false;
CVector<uint8_t> buf;
const uint8_t *data = EcmaString::GetUtf8DataFlat(this, buf);
uint32_t c = data[0];
uint32_t loopStart = 0;
uint64_t n = 0;
if (c == '0') {
*index = 0;
return len == 1;
}
if(c == '-' && len > 1){
negative = true;
loopStart = 1;
}
if (ToUInt64FromLoopStart(&n, loopStart, data) && n < JSObject::MAX_ELEMENT_INDEX) {
*index = negative ? -n : n;
return true;
}
return false;
}
bool EcmaString::ToUInt64FromLoopStart(uint64_t *index, uint32_t loopStart, const uint8_t *data)
{
uint64_t n = 0;
uint32_t len = GetLength();
if (UNLIKELY(loopStart >= len)) {
return false;
}
for (uint32_t i = loopStart; i < len; i++) {
uint32_t c = data[i]; // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (c < '0' || c > '9') {
return false;
}
// NOLINTNEXTLINE(readability-magic-numbers)
n = n * 10 + (c - '0'); // 10: decimal factor
}
*index = n;
return true;
}
bool EcmaString::ToTypedArrayIndex(uint32_t *index)
{
uint32_t len = GetLength();

View File

@ -447,6 +447,10 @@ private:
bool ToElementIndex(uint32_t *index);
bool ToInt(int32_t *index);
bool ToUInt64FromLoopStart(uint64_t *index, uint32_t loopStart, const uint8_t *data);
bool ToTypedArrayIndex(uint32_t *index);
template<bool isLower>
@ -1030,6 +1034,13 @@ public:
return string_->ToElementIndex(index);
}
// not change string data structure.
// if string is not flat, this func has low efficiency.
bool ToInt(int32_t *index)
{
return string_->ToInt(index);
}
// not change string data structure.
// if string is not flat, this func has low efficiency.
bool ToTypedArrayIndex(uint32_t *index)

View File

@ -0,0 +1,18 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("builtins_number") {
deps = []
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
declare function print(arg:any):string;
{
// test new builtin array
let numObj1 = "-100";
print(Number.parseInt(numObj1));
let numObj2 = "1000";
print(Number.parseInt(numObj2));
let numObj3 = "0001030";
print(Number.parseInt(numObj3));
let numObj4 = " -1123";
print(Number.parseInt(numObj4));
}

View File

@ -0,0 +1,17 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
-100
1000
1030
-1123

View File

@ -0,0 +1,18 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_moduletest_action("number") {
deps = []
}

View File

@ -0,0 +1,12 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
{
var numObj = "1234";
const time1 = Date.now()
for(var i = 0; i < 100000; ++i) {
res = Number.parseInt(numObj);
}
const time2 = Date.now()
const time3 = time2 - time1;
print("Number parseInt 1234 : " + time3);
}

View File

@ -0,0 +1,17 @@
#!/bin/bash
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
sed -i 's/print/console.log/g' ./number.js
node number.js
sed -i 's/console.log/print/g' ./number.js