为什么 Dart 中的原生包装函数与非常轻量级的“DEFINE NATIVE ENTRY”函数相比如此重量级?

2024-05-05

我不明白:“为什么要这样保证?”。

这是自定义本机函数的包装器dart/runtime/vm/native_entry.cc:

它适用于想要编写的 Dart 程序员native extensions.

void NativeEntry::NativeCallWrapper(Dart_NativeArguments args,
                                    Dart_NativeFunction func) {
  CHECK_STACK_ALIGNMENT;
  VERIFY_ON_TRANSITION;
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  Isolate* isolate = arguments->isolate();
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  ApiLocalScope* current_top_scope = state->top_scope();
  ApiLocalScope* scope = state->reusable_scope();
  TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func));
  if (scope == NULL) {
    scope = new ApiLocalScope(current_top_scope,
                              isolate->top_exit_frame_info());
    ASSERT(scope != NULL);
  } else {
    scope->Reinit(isolate,
                  current_top_scope,
                  isolate->top_exit_frame_info());
    state->set_reusable_scope(NULL);
  }
  state->set_top_scope(scope);  // New scope is now the top scope.

  func(args);

  ASSERT(current_top_scope == scope->previous());
  state->set_top_scope(current_top_scope);  // Reset top scope to previous.
  if (state->reusable_scope() == NULL) {
    scope->Reset(isolate);  // Reset the old scope which we just exited.
    state->set_reusable_scope(scope);
  } else {
    ASSERT(state->reusable_scope() != scope);
    delete scope;
  }
  DEOPTIMIZE_ALOT;
  VERIFY_ON_TRANSITION;
}

这个包装器在每次调用包装的本机函数时执行所有不必要的检查,使得这些函数与开发人员自己使用的函数相比没有竞争力。

这是用于定义本机函数的宏dart/runtime/vm/native_entry.h:

#define DEFINE_NATIVE_ENTRY(name, argument_count)                              \
  static RawObject* DN_Helper##name(Isolate* isolate,                          \
                                    NativeArguments* arguments);               \
  void NATIVE_ENTRY_FUNCTION(name)(Dart_NativeArguments args) {                \
    CHECK_STACK_ALIGNMENT;                                                     \
    VERIFY_ON_TRANSITION;                                                      \
    NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);     \
    ASSERT(arguments->NativeArgCount() == argument_count);                     \
    TRACE_NATIVE_CALL("%s", ""#name);                                          \
    {                                                                          \
      StackZone zone(arguments->isolate());                                    \
      SET_NATIVE_RETVAL(arguments,                                             \
                        DN_Helper##name(arguments->isolate(), arguments));     \
      DEOPTIMIZE_ALOT;                                                         \
    }                                                                          \
    VERIFY_ON_TRANSITION;                                                      \
  }                                                                            \
  static RawObject* DN_Helper##name(Isolate* isolate,                          \
                                    NativeArguments* arguments)

我知道它可以直接与RawObject。这个是正常的。

但我无法在其中找到所有这些测试,这些测试是在每次调用中执行的,如上面的包装器中所示。

当我看到我的函数比通过定义的类似函数慢 3000% 时,我感到很沮丧DEFINE_NATIVE_ENTRY.

P.S

My native function确实如此NOTHING并且不returns ANYTHING比(例如)此函数慢 500%。

#define TYPED_DATA_GETTER(getter, object, access_size)                         \
DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) {                                   \
  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
  if (instance.IsTypedData()) {                                                \
    const TypedData& array = TypedData::Cast(instance);                        \
    RangeCheck(offsetInBytes.Value(), access_size,                             \
               array.LengthInBytes(), access_size);                            \
    return object::New(array.getter(offsetInBytes.Value()));                   \
  }                                                                            \
  if (instance.IsExternalTypedData()) {                                        \
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
    RangeCheck(offsetInBytes.Value(), access_size,                             \
               array.LengthInBytes(), access_size);                            \
    return object::New(array.getter(offsetInBytes.Value()));                   \
  }                                                                            \
  const String& error = String::Handle(String::NewFormatted(                   \
      "Expected a TypedData object but found %s", instance.ToCString()));      \
  Exceptions::ThrowArgumentError(error);                                       \
  return object::null();                                                       \
}                                                                              \

有没有办法编写不需要所有这些的轻量级本机函数scope?


这是一个老问题,但本机库绝对不是最好的,而且相当重量级。如今,我们通常建议用户考虑使用dart:ffi https://dart.dev/guides/libraries/c-interop对于 C 互操作,它比本机扩展性能更高,并且可以说更易于使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Dart 中的原生包装函数与非常轻量级的“DEFINE NATIVE ENTRY”函数相比如此重量级? 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 在 nHibernate 关系中使用实体的 Lite 版本?

    在某些情况下 出于性能原因 创建一个实体的轻量级版本 指向同一个表 但映射的列较少 这是一个好主意吗 例如 如果我有一个包含 50 列的联系人表 并且在一些相关实体中 我可能对 FirstName 和 LastName 属性感兴趣 那么创建
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • Android Studio Flutter 项目错误:内存不足

    我在 Android Studio 上运行任何 flutter 项目 都会抛出内存不足错误 控制台中显示的消息如下所示 e b build slave windows engine build src third party dart ru
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现

随机推荐