此基准测试似乎表明直接在对象引用上调用虚方法比在对象实现的接口的引用上调用它更快.
换一种说法:
interface IFoo {
void Bar();
}
class Foo : IFoo {
public virtual void Bar() {}
}
void Benchmark() {
Foo f = new Foo();
IFoo f2 = f;
f.Bar(); // This is faster.
f2.Bar();
}
Run Code Online (Sandbox Code Playgroud)
来自C++世界,我原本预计这两个调用都将以相同的方式实现(作为简单的虚拟表查找)并具有相同的性能.C#如何实现虚拟调用以及通过接口调用时显然可以完成的"额外"工作是什么?
好的,答案/评论我到目前为止暗示了通过接口进行虚拟呼叫的双指针解除引用,而不是通过对象进行虚拟呼叫的一个取消引用.
那么请有人解释为什么这是必要的?C#中虚拟表的结构是什么?是否"平坦"(对于C++来说是典型的)或不是?在C#语言设计中做出的设计权衡导致了什么?我不是说这是一个"糟糕"的设计,我只是好奇为什么它是必要的.
简而言之,我想了解我的工具在引擎盖下做了什么,这样我就可以更有效地使用它.如果我不再获得"你不应该知道"或"使用其他语言"类型的答案,我将不胜感激.
为了说清楚,我们没有在这里处理一些JIT优化的编译器,它删除了动态调度:我修改了原始问题中提到的基准,以在运行时随机实例化一个类或另一个类.由于实例化在编译之后和程序集加载/ JITing之后发生,因此在这两种情况下都无法避免动态调度:
interface IFoo {
void Bar();
}
class Foo : IFoo {
public virtual void Bar() {
}
}
class Foo2 : Foo {
public override void Bar() { …Run Code Online (Sandbox Code Playgroud) 我正在为AutoCAD 2009开发一个附加组件.项目输出是一个类库.当我尝试调试并加载类库时,我得到了"LoaderLock被检测到的消息".我一直在写这些附加组件,这是我见过的第一个这种类型的消息.
检测到LoaderLock消息:尝试在OS Loader锁定内执行托管执行.不要尝试在DllMain或图像初始化函数中运行托管代码,因为这样做会导致应用程序挂起.
我去了Debug -> Exceptions -> "Managed Debugging Assistants",找到"LoaderLock"并取消选中了"Thrown"复选框.
我可以再次调试,但我做了什么,为什么我必须这样做?这会给我带来其他问题吗?
假设我们执行......
SELECT * FROM MY_TABLE FOR UPDATE
Run Code Online (Sandbox Code Playgroud)
...... MY_TABLE中有多行.
理论上,如果两个并发事务执行此语句,但它恰好以不同的顺序遍历(并因此锁定)行,则可能发生死锁.例如:
解决此问题的方法是使用ORDER BY来确保始终以相同的顺序锁定行.
所以,我的问题是:这种理论上的僵局会在实践中发生吗?我知道有人工诱导它的方法,但它能否在正常运作中发生?我们应该只使用ORDER BY,还是省略它实际上是安全的?
我主要对Oracle和MySQL/InnoDB的行为感兴趣,但对其他DBMS的评论也会有所帮助.
以下是当锁定顺序不同时,如何在Oracle下重现死锁:
创建测试表并用一些测试数据填充它...
CREATE TABLE DEADLOCK_TEST (
ID INT PRIMARY KEY,
A INT
);
INSERT INTO DEADLOCK_TEST SELECT LEVEL, 1 FROM DUAL CONNECT BY LEVEL <= 10000;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
...从一个客户端会话(我使用SQL Developer),运行以下块:
DECLARE
CURSOR CUR IS
SELECT * FROM DEADLOCK_TEST
WHERE ID BETWEEN 1000 AND 2000
ORDER BY ID
FOR UPDATE;
BEGIN
WHILE TRUE LOOP
FOR LOCKED_ROW IN CUR …Run Code Online (Sandbox Code Playgroud) Visual Studio 2012中是否有命令或插件可以将选定的C#源代码转换SOME_NAME为SomeName?
我承认我并没有尝试对此进行基准测试,但我很好奇......
Enumerable.ToArray<T>(和它的堂兄Enumerable.ToList<T>)的CPU /内存特性是什么?
既然IEnumerable不预先通告它有多少元素,我(可能是天真地)假定ToArray必须"猜测"一个初始数组大小,然后如果第一个猜测看起来太小则重新调整/重新分配数组,然后调整大小如果第二次猜测看起来太小等等,它又会再次出现......这会产生比线性更差的性能.
我可以想象更好的方法涉及(混合)列表,但这仍然需要多个分配(虽然不是重新分配)和相当多的复制,尽管它可能是线性整体尽管开销.
幕后是否有任何"神奇"发生,避免了重复调整大小的需要,并ToArray在空间和时间上呈线性?
更一般地说,是否有关于BCL性能特征的"官方"文档?
解决方案1: 如果我有一个类,
class car{ public: int a; string b; bool c;};
Run Code Online (Sandbox Code Playgroud)
我可以建造200辆汽车的矢量:
std::vector<car> allcas;
allcars.resize(200)
Run Code Online (Sandbox Code Playgroud)
在运行时,我只是这样做:
this_car=allcars[102];
Run Code Online (Sandbox Code Playgroud)
然后 ....
解决方案2:
我有
std::vector<int> a; a.resize(200);
std::vector<string>b; b.resize(200);
std::vector<bool> c; c.resize(200);
this_car_a = a[102];
this_car_b = b[102];
this_car_c = c[102];
Run Code Online (Sandbox Code Playgroud)
问题:哪一个更快?
有没有人有想法?非常感谢!
在 TypeScript 中实现确定性清理的惯用方法是什么?换句话说,是否存在与 C#using (IDisposable)或 C++ 的 RAII 等效的东西?
还是我应该坚持下去finally?
上下文:在 SPA 应用程序(Aurelia / ASP.NET Core Web API)中,我试图向用户指示当前正在从 Web API 获取数据。获取完成后,即使抛出异常,我也想删除 UI 指示。我正在考虑将其包装到“RAII 类”中,以便重用和更清晰的语法(这样我就不必在代码中添加finally)...
有没有办法迫使Oracle"看到"一个表和相关索引比实际更大?
换句话说,有没有办法"伪造"数据库统计数据,因此基于成本的优化器会在几乎空的数据库上做出决策,这更接近于在真实的大型生产数据库中做出的决策?
我们的想法是能够在数据库设计过程的早期阶段用各种索引/查询/(反)规范化策略进行实验(相对于执行计划),而不用浪费时间编写用代表性测试数据填充它的代码(大多数因为数据库设计还没有解决,最终会被丢弃.
导入统计数据是不可能的,因为生产数据库甚至还不存在.
假设下面有一个通用类型,我应该使用什么来代替???正确记录T?
/**
* ??? The description of T.
*/
class MyClass<T> {
}
Run Code Online (Sandbox Code Playgroud)
在 C# 中我会使用<typeparam>. 是否有官方 JSDoc 等效版本?
MySqlCommand cmd = new MySqlCommand
(@"INSERT INTO Table(field) VALUES('somevalue');" +
"SELECT * FROM table",cn);
Run Code Online (Sandbox Code Playgroud)
这对我很好,因为我只是将这些语句传递给我的MySQL服务器.
ExecuteReader()插入,更新和删除时可以使用吗?
我经常使用ExecuteNonQuery()那些.