- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我面临着一个小难题。
我需要在一个类型的许多实例上重复调用给定的方法,这些实例可能存在也可能不存在。因为对于任何给定实例,该方法的结果永远不会改变,所以我缓存它的返回值以供将来使用,以减少开销并在后续调用中尽早返回,但实际执行工作的部分仍然需要调用该 可能不存在的方法:
var method = Context.Parent.GetType().GetMethod("typeHint");
if (method == null)
{
token = null;
_hasTypeHint = false;
return false;
}
var hint = ((dynamic)Context.Parent).typeHint() as VBAParser.TypeHintContext;
token = hint == null ? null : hint.GetText();
return hint != null;
捕获/处理 RuntimeBinderException
是一个主要的性能瓶颈,所以我决定反射(reflection)有问题的类型,并在调用它之前发现该方法是否存在。
Context.Parent
的特定类型在编译时是未知的,并且可能的运行时类型不共享具有 typeHint()
的公共(public)接口(interface)我正在寻找的方法:我需要调用反射成员,或者转换为 dynamic
并直接调用它。
我的提交信息是这样的:
removed the possibility for RuntimeBinderException by reflecting on the context type to locate the method to use. Kept (dynamic) cast because deemed less expensive than reflection invoke.. could be wrong though.
哪一个产生的开销最少,更重要的是,为什么?
最佳答案
好吧,我很好奇,所以我写了一个小程序来测试:
var sw = new Stopwatch();
int loopLimit = 10000000;
object hint1;
sw.Start();
for( var i = 0; i < loopLimit; i++ )
hint1 = ( ( dynamic )theObject ).ToString();
sw.Stop();
Console.WriteLine( "dynamic time: {0}", sw.ElapsedMilliseconds );
sw.Restart();
for( var i = 0; i < loopLimit; i++ )
hint1 = method.Invoke( theObject, null );
sw.Stop();
Console.WriteLine( "invoke time: {0}", sw.ElapsedMilliseconds );
Console.ReadLine();
尝试使用不同的 loopLimit
值,您会发现对于相对较少的调用,Invoke
速度更快。当您增加 loopLimit
时,动态调用会跟上并变得更快。为什么?因为动态调用缓存了执行操作所需的表达式树。在这种情况下,由于我没有更改 theObject
,所以只创建了一个表达式树(在调用站点,每个对象类型将只有一个表达式树)。
所以,长话短说,如果您只调用几千次,或者如果您有大量不同的对象类型要测试和调用,那么表达式树的创建会降低您的性能,Invoke
会更好。如果对象可以是几种类型之一,并且您的方法被调用了数百万次,那么您最好使用 dynamic
调用。
根据您的特定情况使用数字。我猜你会选择 Invoke
。
关于c# - 动态转换与反射调用 : which poison to pick?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35642965/
苏, 我正在尝试对一些嵌套的 Ecto 模型进行编码,但遇到了问题。我意识到我无法对未加载的模型进行编码,并且我希望有可能只选择一个结构而不加载其余部分,同时有可能选择整棵树。 我使用了 defimp
我在几篇论文中发现了“BGP 中毒”和“中毒 AS”的说法,有时它似乎指的是完成某件事以达到某种目的,有时它被认为是坏事,但从未解释过“BGP 中毒”到底是什么” 其实是。 由于我自己无法找到这个问题
我有下面的 Ecto 模型。当我尝试渲染时出现错误。如何修改 @derive 以使其预加载?还是我必须写出实现?处理这个问题的推荐方法是什么? ** (RuntimeError) cannot enc
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
我面临着一个小难题。 我需要在一个类型的许多实例上重复调用给定的方法,这些实例可能存在也可能不存在。因为对于任何给定实例,该方法的结果永远不会改变,所以我缓存它的返回值以供将来使用,以减少开销并在后续
我在 Phoenix 中使用默认的 json 工具,但由于某种原因,我无法返回任何日期(字段类型:日期)。我得到这样的东西: unable to encode value: {2015, 3, 24}
我已创建 Azure 服务总线,并且正在使用 Azure Function 监听消息。 如果我在处理消息期间在 Function 中抛出异常。然后整个过程将重复 10 次,然后消息将被移动到死信队列。
IO.puts(inspect(contacts)) 给出: [%HelloTable.Contact{__meta__: #Ecto.Schema.Metadata, id: 37, in
我使用 crash用于测试 Crashlytics 集成的功能,但我显然不想在应用程序中发布该代码。 标识符中毒是可能的,因此当前或将来的任何使用都会导致错误: #pragma GCC poison
ab = %{a: 1} ac = %{"a" => 1} 具体有什么区别?为什么Poison.decode!返回格式#2(我需要#1 与 Ecto.Changeset.change 一起使用)。 J
我正在开发一个 elixir API,我正在使用 JaSerializer,但在我调用 post API 时它给了我一个类似这样的错误。 function Poison.encode_to_iodat
我正在测试我正在构建的 Webjob 的 Poison 消息处理。 一切似乎都按预期进行,除了一件奇怪的事情: 当一条消息被移动到“-poison”队列时,它的幽灵似乎仍然隐藏在主作业队列中(不可见)
出于阅读目的,我希望在 json 文件中添加特定的按键顺序。 我知道 map 的键没有任何顺序,所以我们不应该依赖它,但由于 Poison 无法对 Prop 列表进行编码,我不知道如何做到这一点。 i
我正在开发一个 elixir API,我正在使用 JaSerializer,但在我调用 post API 时它给了我一个类似这样的错误。 function Poison.encode_to_iodat
我有非常简单的代码,它使用“Poison Pill”模拟生产者/消费者停止技术。 我有生产者类: public class Producer extends Thread { private
我正在为 atmega168a 编写 C 代码。当我编译下面的代码时,出现了 attempt to use poisoned "SIG_OUTPUT_COMPARE0A 和 attempt to us
在 Scott Schurr 演讲的最后 "Introducing constexpr" at CppCon ,他问“有没有办法毒化一个功能”?然后他解释说,这可以通过以下方式完成(尽管以非标准方式)
我是 elixir 的新手,想测试 iex 的 Poison 函数 https://hexdocs.pm/poison/1.3.1/#functions_details iex> Poison.dec
根据 azure 文档,可以通过从 azure-webjobs-hosts 中删除 blob 来重新触发它们。 [...Blob 收据存储在函数应用的 Azure 存储帐户中名为 azure-webj
根据 azure 文档,可以通过从 azure-webjobs-hosts 中删除 blob 来重新触发它们。 [...Blob 收据存储在函数应用的 Azure 存储帐户中名为 azure-webj
我是一名优秀的程序员,十分优秀!