- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在寻找一种方法来解决动态转换类型检查的缓慢问题。在你开始说我应该重新设计一切之前,让我告诉你,设计是 5 年前决定的。我无法修复之后的所有 400,000 行代码(我希望我可以),但我可以进行一些更改。我对类型识别进行了这个小测试:
#include <iostream>
#include <typeinfo>
#include <stdint.h>
#include <ctime>
using namespace std;
#define ADD_TYPE_ID \
static intptr_t type() { return reinterpret_cast<intptr_t>(&type); }\
virtual intptr_t getType() { return type(); }
struct Base
{
ADD_TYPE_ID;
};
template <typename T>
struct Derived : public Base
{
ADD_TYPE_ID;
};
int main()
{
Base* b = new Derived<int>();
cout << "Correct Type: " << (b->getType() == Derived<int>::type()) << endl; // true
cout << "Template Type: " << (b->getType() == Derived<float>::type()) << endl; // false
cout << "Base Type: " << (b->getType() == Base::type()) << endl; // false
clock_t begin = clock();
{
for (size_t i = 0; i < 100000000; i++)
{
if (b->getType() == Derived<int>::type())
Derived <int>* d = static_cast<Derived<int>*> (b);
}
}
clock_t end = clock();
double elapsed = double(end - begin) / CLOCKS_PER_SEC;
cout << "Type elapsed: " << elapsed << endl;
begin = clock();
{
for (size_t i = 0; i < 100000000; i++)
{
Derived<int>* d = dynamic_cast<Derived<int>*>(b);
if (d);
}
}
end = clock();
elapsed = double(end - begin) / CLOCKS_PER_SEC;
cout << "Type elapsed: " << elapsed << endl;
begin = clock();
{
for (size_t i = 0; i < 100000000; i++)
{
Derived<int>* d = dynamic_cast<Derived<int>*>(b);
if ( typeid(d) == typeid(Derived<int>*) )
static_cast<Derived<int>*> (b);
}
}
end = clock();
elapsed = double(end - begin) / CLOCKS_PER_SEC;
cout << "Type elapsed: " << elapsed << endl;
return 0;
}
似乎使用类 ID(上面的第一次解决方案)将是在运行时进行类型检查的最快方法。这会导致线程问题吗?有没有更好的方法在运行时检查类型(不需要太多重构)?
编辑:我还可以补充一点,这需要与 TI 编译器一起使用,该编译器目前仅支持最多 '03
最佳答案
首先,请注意 dynamic_cast
和 RTTI 之间存在很大差异:强制转换告诉您是否可以将基础对象视为进一步派生的 some,但不一定最衍生的对象。 RTTI 会告诉您最精确的派生类型。自然前者更强大,也更昂贵。
那么,如果您有一个多态层次结构,您可以通过两种自然的方式来选择类型。他们是不同的;使用实际适用的那个。
void method1(Base * p)
{
if (Derived * q = dynamic_cast<Derived *>(p))
{
// use q
}
}
void method2(Base * p)
{
if (typeid(*p) == typeid(Derived))
{
auto * q = static_cast<Derived *>(p);
// use q
}
}
另请注意,如果基类是虚拟基类,则方法 2 通常不可用。如果您的类不是多态的,则这两种方法都不适用。
在快速测试中,我发现方法 2 比基于 ID 的手动解决方案快得多,后者又比动态转换解决方案(方法 1)快。
关于c++ - 在遗留代码上规避 RTTI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25495733/
假设我有一个像这样的字符串:'1 + 2 + 3 * 4' 是否可以从左到右(顺序?线性?)计算它,使其等于 24 而不 15? 我事先不知道该字符串是什么,所以它可能是“1 + 2”,也可能是“1
我在脚本中得到了这一行,它检查项目类: $('#post').attr('class'); 有没有机会,读起来像: $('#post*').attr('class'); 所以如果 ID 是 fe。 p
将我的工具链安装在与其供应商要求的目录不同的目录中后,我一直在运行一些较小的问题,通过适本地设置 COMPILER_PATH、C_INCLUDE_PATH、CPLUS_INCLUDE_PATH 和 L
我正在使用 boost::program_options,它与许多其他 C++ 库一样受到同样的困扰,甚至是 std 本身:它仍然使用 C 风格的空终止字符串,因为没有人真正喜欢弱 std::字符串.
Peter Norvig 在 PAIP 中说道: in modern lisps...eval is used less often (in fact, in Scheme there isno ev
我有一个这样工作的程序: prog.py filename -r 使用我给定的默认默认值 prog.py filename -r 0 500 20 使用 0、500 和 20 我已经成功地使用了: c
我正在使用 Java 程序进行一些图像处理,目前我正在处理一些相当大的图像(大约十亿像素)。 毫不奇怪,由于以下异常,我无法做很多事情: Exception: java.lang.IllegalArg
所以我想用Scrapy做一个steam游戏的刷屏器。我不知道为什么有些游戏没有显示在结果 csv/json 中。我认为这是因为年龄验证表。 我真的很想看看问题出在哪里......但一切似乎都应该有效。
我正在尝试控制我的表单以及用户如何通过表单元素的 tabindex 属性与它们交互。我的所有元素都指定了 tabindex,我希望这个值得到尊重并得到正确使用。 我目前正在 Mac/Firefox 上
我将实现一个简单的链表。这是我到目前为止的(工作)代码: pub struct LinkedList { start: Option>>, } impl LinkedList { pu
我遇到了 IE8 的 31 个 CSS 文件限制。 我在想,除非我弄错了,否则 Assets 管道会结合我的 CSS 文件进行生产,因此这不会成为问题。 然而,当我为 IE 调试时,这是一个问题。有没
我正在尝试在 Yacc/Bison 中创建一个 LALR(1) 解析器,它可以接受具有灵活语法的命令。一个例子是通过调整室温( float )、 window 位置(整数)和吊扇(枚举)来控制房屋中的
为了调试,我想用 JSON.stringify(myobject) 序列化 javascript 对象。但这给出了: TypeError: Converting circular structure
我正在使用交叉 musl 编译器(相同版本)构建 native musl 编译器 (GCC 8.3.0),但出现此错误: In file included from /usr/local/x86_64
我是一名优秀的程序员,十分优秀!