* Copyright (c) 2025 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.
*/
#include <ctime>
#include <sys/time.h>
#include "gtest/gtest.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "native_engine.h"
#include "native_engine/impl/ark/ark_native_engine.h"
using panda::RuntimeOption;
static constexpr int NUM_COUNT = 10000;
static constexpr int TIME_UNIT = 1000000;
time_t g_timeFor = 0;
struct timeval g_beginTime;
struct timeval g_endTime;
time_t g_time1 = 0;
time_t g_time2 = 0;
time_t g_time = 0;
#define TEST_TIME(NAME) \
{ \
g_time1 = (g_beginTime.tv_sec * TIME_UNIT) + (g_beginTime.tv_usec); \
g_time2 = (g_endTime.tv_sec * TIME_UNIT) + (g_endTime.tv_usec); \
g_time = g_time2 - g_time1; \
GTEST_LOG_(INFO) << "name =" << #NAME << " = Time =" << int(g_time - g_timeFor); \
}
class ArkNapiPerfomanceTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
CreateEngine(vm_, nativeEngine_);
}
void TearDown() override
{
nativeEngine_->Loop(LOOP_NOWAIT);
DestroyEngine(vm_, nativeEngine_);
}
void CreateEngine(EcmaVM*& vm, NativeEngine*& engine)
{
RuntimeOption option;
option.SetGcType(RuntimeOption::GC_TYPE::GEN_GC);
const int64_t poolSize = 0x1000000;
option.SetGcPoolSize(poolSize);
option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
option.SetDebuggerLibraryPath("");
vm = panda::JSNApi::CreateJSVM(option);
engine = new ArkNativeEngine(vm, nullptr);
}
void DestroyEngine(EcmaVM*& vm, NativeEngine*& engine)
{
if (engine != nullptr) {
delete engine;
engine = nullptr;
}
if (vm != nullptr) {
panda::JSNApi::DestroyJSVM(vm);
vm = nullptr;
}
}
EcmaVM* vm_ {nullptr};
NativeEngine* nativeEngine_ {nullptr};
};
HWTEST_F(ArkNapiPerfomanceTest, GetBoolean001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
napi_get_boolean(env, true, &result);
bool resultValue = false;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_value_bool(env, result, &resultValue);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_value_bool);
}
HWTEST_F(ArkNapiPerfomanceTest, GetValueDouble001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
napi_create_double(env, 20.22, &result);
double resultValue = 0;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_value_double(env, result, &resultValue);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_value_double);
}
HWTEST_F(ArkNapiPerfomanceTest, GetValueInt32, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
napi_create_int32(env, 20, &result);
int32_t resultValue = 0;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_value_int32(env, result, &resultValue);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_value_int32);
}
HWTEST_F(ArkNapiPerfomanceTest, GetValueUint32, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
napi_create_uint32(env, 20, &result);
uint32_t resultValue = 0;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_value_uint32(env, result, &resultValue);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_value_uint32);
}
HWTEST_F(ArkNapiPerfomanceTest, GetValueInt64, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
napi_create_int64(env, 200, &result);
int64_t resultValue = 0;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_value_int64(env, result, &resultValue);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_value_int64);
}
HWTEST_F(ArkNapiPerfomanceTest, GetValueStringUtf8, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
const char testStr[] = "ut.utf8test.napi.!@#$%^&*123";
size_t testStrLength = strlen(testStr);
size_t copied = 0;
napi_value result = nullptr;
napi_create_string_utf8(env, testStr, testStrLength, &result);
char *buffer = new char[testStrLength + 1]{ 0 };
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_value_string_utf8(env, result, buffer, testStrLength + 1, &copied);
}
gettimeofday(&g_endTime, nullptr);
delete []buffer;
buffer = nullptr;
TEST_TIME(napi_get_value_string_utf8);
}
HWTEST_F(ArkNapiPerfomanceTest, GetNull, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_null(env, &result);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_null);
}
HWTEST_F(ArkNapiPerfomanceTest, GetUndefined, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value result = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_undefined(env, &result);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_null);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateObject, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value object = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_object(env, &object);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_object);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateInt32, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res = nullptr;
int32_t num = 123;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_int32(env, num, &res);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_int32);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateInt64, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res = nullptr;
int64_t num = 123456;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_int64(env, num, &res);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_int32);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateUint32, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res = nullptr;
uint32_t num = 123;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_uint32(env, num, &res);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_uint32);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateStringUtf8, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
const char testStr[] = "ut.utf8test.napi.!@#$%^&*123";
size_t testStrLength = strlen(testStr);
napi_value result = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_string_utf8(env, testStr, testStrLength, &result);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_string_utf8);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateDouble, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res = nullptr;
double num = 123.001;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_double(env, num, &res);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_double);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateStringLatin1, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value messageKey = nullptr;
const char* messageKeyStr = "message";
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_string_latin1);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateArray001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value array = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_array(env, &array);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_array);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateArrayWithLength001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value array = nullptr;
size_t length = 8;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_array_with_length(env, length, &array);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_array_with_length);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateSymbol, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
const char* testStr1 = "testSymbol";
napi_value result1 = nullptr;
napi_create_string_latin1(env, testStr1, strlen(testStr1), &result1);
napi_value symbolVal = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_symbol(env, result1, &symbolVal);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_symbol);
}
napi_value SayHello(napi_env env, napi_callback_info info)
{
return NULL;
}
HWTEST_F(ArkNapiPerfomanceTest, CreateFunction, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value fn = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_function(env, NULL, 0, SayHello, NULL, &fn);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_function);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateError, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value code = nullptr;
napi_value message = nullptr;
napi_create_string_latin1(env, "500", NAPI_AUTO_LENGTH, &code);
napi_create_string_latin1(env, "common error", NAPI_AUTO_LENGTH, &message);
napi_value error = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_error(env, code, message, &error);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_error);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateTypeError, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value code1 = nullptr;
napi_value message1 = nullptr;
napi_create_string_latin1(env, "500", NAPI_AUTO_LENGTH, &code1);
napi_create_string_latin1(env, "type error", NAPI_AUTO_LENGTH, &message1);
napi_value error1 = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_type_error(env, code1, message1, &error1);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_type_error);
}
HWTEST_F(ArkNapiPerfomanceTest, CreateRangeError, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value code2 = nullptr;
napi_value message2 = nullptr;
napi_create_string_latin1(env, "500", NAPI_AUTO_LENGTH, &code2);
napi_create_string_latin1(env, "range error", NAPI_AUTO_LENGTH, &message2);
napi_value error2 = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_create_range_error(env, code2, message2, &error2);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_create_range_error);
}
HWTEST_F(ArkNapiPerfomanceTest, CoerceToBool, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
bool val = false;
napi_value res = nullptr;
napi_value result = nullptr;
napi_get_boolean(env, val, &res);
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_coerce_to_bool(env, res, &result);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_coerce_to_bool);
}
HWTEST_F(ArkNapiPerfomanceTest, CoerceToNumber, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
double num1 = 10.3;
napi_value res1 = nullptr;
napi_value result1 = nullptr;
napi_create_double(env, num1, &res1);
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_coerce_to_number(env, res1, &result1);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_coerce_to_number);
}
HWTEST_F(ArkNapiPerfomanceTest, CoerceToObject, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value obj = nullptr;
napi_value res2 = nullptr;
napi_create_object(env, &obj);
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_coerce_to_object(env, obj, &res2);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_coerce_to_object);
}
HWTEST_F(ArkNapiPerfomanceTest, CoerceToString, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
const char* testStringStr = "test";
napi_value testString = nullptr;
napi_create_string_utf8(env, testStringStr, strlen(testStringStr), &testString);
napi_value res3 = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_coerce_to_string(env, testString, &res3);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_coerce_to_string);
}
HWTEST_F(ArkNapiPerfomanceTest, SetProperty, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res4 = nullptr;
napi_create_object(env, &res4);
napi_value messageKey = nullptr;
const char* messageKeyStr = "message";
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
napi_value messageValue = nullptr;
const char* messageValueStr = "ok";
napi_create_string_latin1(env, messageValueStr, strlen(messageValueStr), &messageValue);
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_set_property(env, res4, messageKey, messageValue);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_set_property);
}
HWTEST_F(ArkNapiPerfomanceTest, GetPrototype, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res4 = nullptr;
napi_create_object(env, &res4);
napi_value res5 = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_prototype(env, res4, &res5);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_prototype);
}
HWTEST_F(ArkNapiPerfomanceTest, HasProperty, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res4 = nullptr;
napi_create_object(env, &res4);
napi_value messageKey = nullptr;
const char* messageKeyStr = "message";
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
napi_value messageValue = nullptr;
const char* messageValueStr = "ok";
napi_create_string_latin1(env, messageValueStr, strlen(messageValueStr), &messageValue);
bool hasProperty = false;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_has_property(env, res4, messageKey, &hasProperty);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_has_property);
}
HWTEST_F(ArkNapiPerfomanceTest, GetProperty, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res4 = nullptr;
napi_create_object(env, &res4);
napi_value messageKey = nullptr;
const char* messageKeyStr = "message";
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
napi_value messageValue = nullptr;
const char* messageValueStr = "ok";
napi_create_string_latin1(env, messageValueStr, strlen(messageValueStr), &messageValue);
napi_value res6 = nullptr;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_get_property(env, res4, messageKey, &res6);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_get_property);
}
HWTEST_F(ArkNapiPerfomanceTest, HasOwnProperty, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res4 = nullptr;
napi_create_object(env, &res4);
napi_value messageKey = nullptr;
const char* messageKeyStr = "message";
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
napi_value messageValue = nullptr;
const char* messageValueStr = "ok";
napi_create_string_latin1(env, messageValueStr, strlen(messageValueStr), &messageValue);
bool res7 = false;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_has_own_property(env, res4, messageKey, &res7);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_has_own_property);
}
HWTEST_F(ArkNapiPerfomanceTest, DeleteProperty, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res4 = nullptr;
napi_create_object(env, &res4);
napi_value messageKey = nullptr;
const char* messageKeyStr = "message";
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
napi_value messageValue = nullptr;
const char* messageValueStr = "ok";
napi_create_string_latin1(env, messageValueStr, strlen(messageValueStr), &messageValue);
bool res8 = false;
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_delete_property(env, res4, messageKey, &res8);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_delete_property);
}
HWTEST_F(ArkNapiPerfomanceTest, SetNameProperty, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)nativeEngine_;
napi_value res9 = nullptr;
napi_create_object(env, &res9);
const char testStr[] = "1234567";
napi_value strAttribute = nullptr;
napi_create_string_utf8(env, testStr, strlen(testStr), &strAttribute);
gettimeofday(&g_beginTime, nullptr);
for (int i = 0; i < NUM_COUNT; i++) {
napi_set_named_property(env, res9, "strAttribute", strAttribute);
}
gettimeofday(&g_endTime, nullptr);
TEST_TIME(napi_set_named_property);
}