optimize double2ecmastring

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAJODL
Description:
optimize double2ecmastring, not use std::string

Change-Id: Ifb0ba983f6327e093ca1b4940361f347fd2f9636
Signed-off-by: duomingliang <duomingliang@huawei.com>
This commit is contained in:
duomingliang 2024-08-13 14:43:15 +08:00
parent f5d2b7ca16
commit fd204178a0
3 changed files with 181 additions and 20 deletions

View File

@ -709,44 +709,71 @@ JSHandle<EcmaString> NumberHelper::DoubleToEcmaString(const JSThread *thread, do
return factory->NewFromASCII(IntToString(static_cast<int32_t>(d)));
}
std::string result;
if (std::isinf(d)) {
return d < 0 ? JSHandle<EcmaString>::Cast(thread->GlobalConstants()->GetHandledMinusInfinityCapitalString())
: JSHandle<EcmaString>::Cast(thread->GlobalConstants()->GetHandledInfinityCapitalString());
}
char buffer[JS_DTOA_BUF_SIZE] = {0};
bool isNeg = false;
if (d < 0) {
result += "-";
isNeg = true;
d = -d;
}
if (std::isinf(d)) {
result += "Infinity";
return factory->NewFromASCII(result.c_str());
}
ASSERT(d > 0);
char buffer[JS_DTOA_BUF_SIZE] = {0};
constexpr int startIdx = 8;
char *result = buffer + startIdx;
int n; // decimal point
int k; // length
DtoaHelper::Dtoa(d, buffer, &n, &k); //Fast Double To Ascii.
std::string base = buffer;
DtoaHelper::Dtoa(d, result, &n, &k); //Fast Double To Ascii.
if (n > 0 && n <= MAX_DIGITS) {
if (k <= n) {
// 6. If k ≤ n ≤ 21
base += std::string(n - k, '0');
for (int i = k; i < n; ++i) {
result[i] = '0';
}
} else {
// 7. If 0 < n ≤ 21
base.insert(n, 1, '.');
--result;
for (int i = 0; i < n; ++i) {
result[i] = result[i + 1];
}
result[n] = '.';
}
} else if (MIN_DIGITS < n && n <= 0) {
// 8. If 6 < n ≤ 0
base = std::string("0.") + std::string(-n, '0') + base;
constexpr int prefixLen = 2;
result -= (-n + prefixLen);
result[0] = '0';
result[1] = '.';
for (int i = prefixLen; i < -n + prefixLen; ++i) {
result[i] = '0';
}
} else {
// 9. & 10. Otherwise
base.erase(1, k - 1);
int pos = k;
if (k != 1) {
base += std::string(".") + std::string(buffer + 1);
--result;
result[0] = result[1];
result[1] = '.';
++pos;
}
result[pos++] = 'e';
if (n >= 1) {
result[pos++] = '+';
}
auto expo = std::to_string(n - 1);
auto p = expo.c_str();
for (size_t i = 0; i < expo.length(); ++i) {
result[pos++] = p[i];
}
base += "e" + (n >= 1 ? std::string("+") : "") + std::to_string(n - 1);
}
result += base;
return factory->NewFromASCIISkippingStringTable(result.c_str());
if (isNeg) {
--result;
result[0] = '-';
}
return factory->NewFromASCIISkippingStringTable(result);
}
// 7.1.12.1 ToString Applied to the Number Type

View File

@ -178,6 +178,138 @@ HWTEST_F_L0(NumberHelperTest, DoubleToEcmaString)
double d6 = 340000000000000000;
JSHandle<EcmaString> resultJSHandle6 = NumberHelper::DoubleToEcmaString(thread, d6);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle6, resultStr6), 0);
JSHandle<EcmaString> resultStr7 =
factory->NewFromASCII("12.012345678901234");
double d7 = 12.01234567890123456789;
JSHandle<EcmaString> resultJSHandle7 = NumberHelper::DoubleToEcmaString(thread, d7);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle7, resultStr7), 0);
JSHandle<EcmaString> resultStr8 =
factory->NewFromASCII("0.0000012345678901234567");
double digit8 = 0.000001234567890123456789;
JSHandle<EcmaString> resultJSHandle8 = NumberHelper::DoubleToEcmaString(thread, digit8);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle8, resultStr8), 0);
JSHandle<EcmaString> resultStr9 =
factory->NewFromASCII("Infinity");
double d9 = std::numeric_limits<double>::infinity();
JSHandle<EcmaString> resultJSHandle9 = NumberHelper::DoubleToEcmaString(thread, d9);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle9, resultStr9), 0);
JSHandle<EcmaString> resultStr10 =
factory->NewFromASCII("-Infinity");
double d10 = -std::numeric_limits<double>::infinity();
JSHandle<EcmaString> resultJSHandle10 = NumberHelper::DoubleToEcmaString(thread, d10);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle10, resultStr10), 0);
JSHandle<EcmaString> resultStr11 =
factory->NewFromASCII("1.7976931348623157e+308");
double d11 = 1.797693134862315807937e+308;
JSHandle<EcmaString> resultJSHandle11 = NumberHelper::DoubleToEcmaString(thread, d11);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle11, resultStr11), 0);
JSHandle<EcmaString> resultStr12 =
factory->NewFromASCII("-1.7976931348623157e+308");
double d12 = -1.797693134862315807937e+308;
JSHandle<EcmaString> resultJSHandle12 = NumberHelper::DoubleToEcmaString(thread, d12);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle12, resultStr12), 0);
JSHandle<EcmaString> resultStr13 =
factory->NewFromASCII("2.22507e-308");
double d13 = 2.22507e-308;
JSHandle<EcmaString> resultJSHandle13 = NumberHelper::DoubleToEcmaString(thread, d13);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle13, resultStr13), 0);
JSHandle<EcmaString> resultStr14 =
factory->NewFromASCII("1.2345678901234568e-7");
double digit14 = 0.0000001234567890123456789;
JSHandle<EcmaString> resultJSHandle14 = NumberHelper::DoubleToEcmaString(thread, digit14);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle14, resultStr14), 0);
JSHandle<EcmaString> resultStr15 =
factory->NewFromASCII("3.4e+21");
double digit15 = 3.4e21;
JSHandle<EcmaString> resultJSHandle15 = NumberHelper::DoubleToEcmaString(thread, digit15);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle15, resultStr15), 0);
JSHandle<EcmaString> resultStr16 =
factory->NewFromASCII("120000000000000000000");
double digit16 = 1.2e20;
JSHandle<EcmaString> resultJSHandle16 = NumberHelper::DoubleToEcmaString(thread, digit16);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle16, resultStr16), 0);
JSHandle<EcmaString> resultStr17 =
factory->NewFromASCII("1.2");
double digit17 = 1.2e0;
JSHandle<EcmaString> resultJSHandle17 = NumberHelper::DoubleToEcmaString(thread, digit17);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle17, resultStr17), 0);
JSHandle<EcmaString> resultStr18 =
factory->NewFromASCII("0.0000012");
double digit18 = 1.2e-6;
JSHandle<EcmaString> resultJSHandle18 = NumberHelper::DoubleToEcmaString(thread, digit18);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle18, resultStr18), 0);
JSHandle<EcmaString> resultStr19 =
factory->NewFromASCII("1.2e-7");
double digit19 = 1.2e-7;
JSHandle<EcmaString> resultJSHandle19 = NumberHelper::DoubleToEcmaString(thread, digit19);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle19, resultStr19), 0);
JSHandle<EcmaString> resultStr20 =
factory->NewFromASCII("NaN");
double digit20 = std::numeric_limits<double>::quiet_NaN();
JSHandle<EcmaString> resultJSHandle20 = NumberHelper::DoubleToEcmaString(thread, digit20);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle20, resultStr20), 0);
JSHandle<EcmaString> resultStr21 =
factory->NewFromASCII("-12.012345678901234");
double d21 = -12.01234567890123456789;
JSHandle<EcmaString> resultJSHandle21 = NumberHelper::DoubleToEcmaString(thread, d21);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle21, resultStr21), 0);
JSHandle<EcmaString> resultStr22 =
factory->NewFromASCII("-0.0000012345678901234567");
double digit22 = -0.000001234567890123456789;
JSHandle<EcmaString> resultJSHandle22 = NumberHelper::DoubleToEcmaString(thread, digit22);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle22, resultStr22), 0);
JSHandle<EcmaString> resultStr23 =
factory->NewFromASCII("-1.2345678901234568e-7");
double digit23 = -0.0000001234567890123456789;
JSHandle<EcmaString> resultJSHandle23 = NumberHelper::DoubleToEcmaString(thread, digit23);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle23, resultStr23), 0);
JSHandle<EcmaString> resultStr24 =
factory->NewFromASCII("-3.4e+21");
double digit24 = -3.4e21;
JSHandle<EcmaString> resultJSHandle24 = NumberHelper::DoubleToEcmaString(thread, digit24);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle24, resultStr24), 0);
JSHandle<EcmaString> resultStr25 =
factory->NewFromASCII("-120000000000000000000");
double digit25 = -1.2e20;
JSHandle<EcmaString> resultJSHandle25 = NumberHelper::DoubleToEcmaString(thread, digit25);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle25, resultStr25), 0);
JSHandle<EcmaString> resultStr26 =
factory->NewFromASCII("-1.2");
double digit26 = -1.2e0;
JSHandle<EcmaString> resultJSHandle26 = NumberHelper::DoubleToEcmaString(thread, digit26);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle26, resultStr26), 0);
JSHandle<EcmaString> resultStr27 =
factory->NewFromASCII("-0.0000012");
double digit27 = -1.2e-6;
JSHandle<EcmaString> resultJSHandle27 = NumberHelper::DoubleToEcmaString(thread, digit27);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle27, resultStr27), 0);
JSHandle<EcmaString> resultStr28 =
factory->NewFromASCII("-1.2e-7");
double digit28 = -1.2e-7;
JSHandle<EcmaString> resultJSHandle28 = NumberHelper::DoubleToEcmaString(thread, digit28);
EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultJSHandle28, resultStr28), 0);
}
/**
@ -721,4 +853,4 @@ HWTEST_F_L0(NumberHelperTest, DoubleToASCII_002)
EXPECT_EQ(EcmaStringAccessor::Compare(instance, handleEcmaStr7, resultStr), 0);
}
} // namespace panda::ecmascript
} // namespace panda::ecmascript

View File

@ -466,6 +466,8 @@ class ObjectFactory;
V(IntegerString, INTEGER_STRING_INDEX, "integer") \
V(NanString, NAN_STRING_INDEX, "nan") \
V(InfinityString, INFINITY_STRING_INDEX, "infinity") \
V(InfinityCapitalString, INFINITY_CAP_STRING_INDEX, "Infinity") \
V(MinusInfinityCapitalString, MINUS_INFINITY_CAP_STRING_INDEX, "-Infinity") \
V(FractionString, FRACTION_STRING_INDEX, "fraction") \
V(DecimalString, DECIMAL_STRING_INDEX, "decimal") \
V(GroupString, GROUP_STRING_INDEX, "group") \