Performance QGraphicscene,项目坐标是否影响性能?

Performance QGraphicscene,项目坐标是否影响性能?,performance,qt,qgraphicsscene,Performance,Qt,Qgraphicsscene,使用下面的代码片段,我创建了一个具有100.000个矩形的场景。 性能优良;视图没有延迟地响应 QGraphicsScene * scene = new QGraphicsScene; for (int y = -50000; y < 50000; y++) { scene->addRect(0, y * 25, 40, 20); } ... view->setScene(scene); qgraphicscene*场景=新的qgraphicscene; 对于(int

使用下面的代码片段,我创建了一个具有100.000个矩形的场景。
性能优良;视图没有延迟地响应

QGraphicsScene * scene = new QGraphicsScene;
for (int y = -50000; y < 50000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}
...
view->setScene(scene);
qgraphicscene*场景=新的qgraphicscene;
对于(int y=-50000;y<50000;y++){
场景->addRect(0,y*25,40,20);
}
...
查看->设置场景(场景);
现在第二个片段糟透了

for (int y = 0; y < 100000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}
for(int y=0;y<100000;y++){
场景->addRect(0,y*25,40,20);
}
对于场景元素的前半部分,视图延迟响应鼠标和按键事件,而对于另一半,它似乎正常

前一个场景有(x,y,w,h)=(0,-1250000,402499995)。
后一个场景具有(x,y,w,h)=(0,0,40,2499995)

由于BSP索引是基于相对项坐标的,我不知道SCENERTIONG为什么会影响性能

我错过什么了吗?我没有找到文件上的任何信息, 另外,Qt演示还将元素分布在(0,0)周围,而不解释选择的原因

 // Populate scene
 int xx = 0;
 int nitems = 0;
 for (int i = -11000; i < 11000; i += 110) {
     ++xx;
     int yy = 0;
     for (int j = -7000; j < 7000; j += 70) {
         ++yy;
         qreal x = (i + 11000) / 22000.0;
         qreal y = (j + 7000) / 14000.0;
         ...
//填充场景
int xx=0;
int nitems=0;
对于(int i=-11000;i<11000;i+=110){
++xx;
int-yy=0;
对于(int j=-7000;j<7000;j+=70){
++yy;
qreal x=(i+11000)/22000.0;
qreal y=(j+7000)/14000.0;
...

我有一个解决方案给你,但我保证不会问我为什么这样做有效, 因为我真的不知道:-)

qgraphicscene*场景=新的qgraphicscene;
//定义一个伪对称场景矩形
场景->设置场景(0,-(25*100000+20),40,2*(25*100000+20));
对于(int y=0;y<100000;y++){
场景->addRect(0,y*25,40,20);
}
查看->设置场景(场景);
//告诉视图仅显示实际场景对象区域
视图->设置竖立(0,0,40,25*100000+20);
对于常见情况,默认索引 方法BSPTREINDEX工作正常。如果 您的场景使用了许多动画和动画 你正在经历缓慢,你可以 通过调用禁用索引 setItemIndexMethod(NoIndex)

在插入之前,您需要调用
setItemIndexMethod(QGraphicscene::NoIndex)

scene->setItemIndexMethod(QGraphicsScene::NoIndex);

for (int y = 0; y < 100000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}
//...
scene->setItemIndexMethod(QGraphicscene::NoIndex);
对于(int y=0;y<100000;y++){
场景->addRect(0,y*25,40,20);
}
//...

这可能是由于
float
的精度损失造成的。32位float有23位尾数(或有效位)、1位符号和8位指数。这就像科学记数法。你有23个“有效数字”(实际上是24位,因为隐式前导1)和2^exp的指数,其中指数的范围为-126到127(其他的是用来给你像
NaN
Inf
)这样的数字。所以你可以表示非常大的数字,比如2^24*2^127,但是下一个最接近这个浮点数的浮点数是(2^24-1)*2^127或1700亿。如果你尝试添加一个较小的数字(比如1000)对于这样一个数字,它不会改变,它无法表示

这在计算机图形学中变得非常重要,因为您需要一些剩余的有效数字来制作分数部分。当场景范围达到1250000.0时,您可以将0.1添加到该范围中,得到1250000.1。如果使用2500000.0+0.1,则得到2500000.0。出现的任何缩放或旋转都会放大该问题。这可能导致如果你真的飞到那些坐标系去看你的场景,会有明显的视觉问题

为什么以0为中心有帮助?因为在浮点表示法中有一个单独的符号位。在浮点表示法中(-x,+x)之间的数字比(0,2x)之间的数字“更多”.如果我是对的,如果你简单地将整个场景缩小1/2,它也会起作用。这会将最重要的部分向下移动,使另一端的精度保持不变


<>为什么这会导致性能不佳?我只能在不读取Qt源的情况下进行推测,但是考虑一个数据结构来存储对象的位置。如果两个对象接触(或重叠),您可能需要做些什么不同的操作?由于精度损失,当它们没有重叠时,您不必这样做?

我的第一个猜测是重新计算场景矩形。如果您在添加项目之前设置场景竖立,会发生什么情况?@Stephen,结果是一样的。即使场景已准备就绪且静止,视图也会延迟响应。哇,非常令人惊讶。我运行了一些测试,结果是这样的ems表示,只有在查看1-50000个框时,小部件才会变得滞后。之后,即50.001-100.000,一切都很顺利。更令人担忧的是,如果我的范围
为(int y=-70000;y<30000;y++)
…然后滚动平滑到-70.000//-20.000,延迟到-20.000/0,然后再平滑到0/30.000!当然我真的很想知道这种行为的原因。Qt中有个bug,还是别的什么?赏金是你的,Fivo,但案件仍在审理中:)谢谢Nick,虽然我不觉得我真的提供了一个解决方案,但只是一个解决办法。如果你在Qt网站上提交了一个bug,请让我们随时更新任何官方解决方案;-)这不是我要找的,Red Hue。如果场景包含数十万或数百万项,禁用索引不是一个好主意。我想要的是跟踪问题的根源这种奇怪的行为。另外,我已经知道了一种加快代码速度的解决方法,Fivos Vilanakis发布了另一种。@Nick Dandoulakis你有错误报告吗?但这是错误吗?可能是设计造成的。无论如何,制作报告是个好主意。插入项目后,你总是可以再次启用BSP索引。不确定这是否仍然利用了错误或错误不是。嗨,本。我只是尝试了你的假设,将量表从2.500.000降到1.000.000,甚至降到500.000,但没有任何改进。我假设问题(或错误?)与精度无关,但主要与Qt QGraphicsView在QGraphicsView视口为ref时如何使用QGraphicsCenter的BSP索引剪裁场景对象有关
scene->setItemIndexMethod(QGraphicsScene::NoIndex);

for (int y = 0; y < 100000; y++) {
   scene->addRect(0, y * 25, 40, 20);
}
//...