English 中文(简体)
优化资格选择
原标题:Optimizing quadrant selection

我正在建立一个数据结构,将各种物品归入零件,而我所发现的瓶颈之一是我选择该点的宽度的方法。 诚然,它非常简单,但它多次呼吁它增加。 我认为,要把这个问题推向我想要的东西,就必须是一个有效的办法,但我却不能认为。

private int Quadrant(Point p)
{
    if (p.X >= Center.X)
        return p.Y >= Center.Y ? 0 : 3;
    return p.Y >= Center.Y ? 1 : 2;
}

<代码>Center为<>>>>>,坐标为ints。 是的,我已经掌握了一部法典,没有,这是过早优化的。


由于这只是内部使用的,因此,我假定我的四分数不上,请上,只要从0到3不等,则由Cartesian Order

最佳回答

C/C++中最快的方式将是

(((unsigned int)x >> 30) & 2) | ((unsigned int)y >> 31)

(30/31 or 62/63, depending on size of int). This will give the quadrants in order 0, 2, 3, 1.

Edit for LBushkin:

(((unsigned int)(x - center.x) >> 30) & 2) | ((unsigned int)(y-center.y) >> 31)
问题回答

我不知道,你可以在C#中迅速使这一法典迅速生效。 然而,你可以做些什么,看你如何重新处理点,看看你能否避免对这种方法发出不必要的呼吁。 也许你可以建立一个<条码>QuadPoint的结构,储存一个点(在你一劳永逸之后),以便你不必再做。

但大家承认,这取决于贵算法正在做什么,以及是否可能储存/纪念假信息。 如果每一点都是完全独特的,这显然就赢得了帮助。

刚才有人告诉我,解决办法产生了0,1,2,3类错误结果,是正确的:

#define LONG_LONG_SIGN (sizeof(long long) * 8 - 1)

double dx = point.x - center.x;
double dy = point.y - center.y;

long long *pdx = (void *)&dx;
long long *pdy = (void *)&dy;

int quadrant = ((*pdy >> LONG_LONG_SIGN) & 3) ^ ((*pdx >> LONG_LONG_SIGN) & 1);

这一解决办法是Xy坐标。

我先对这种方法和按原始问题划分的方法进行了一些业绩测试:我的结果是,分管方法总是比较快(目前我有稳定的160/180关系),因此,我倾向于采用分机操作方法。


<>>>>>

如果有人有兴趣,所有三个算法均并入https://github.com/Evgeny Karkan/EKAlgorithms” rel=“nofollow”>。 EKAlgorithms C/Objective-C Deposit,作为“便利选择”算法:

  1. Original branching algorithm
  2. Bitwise algorithm by @ruslik from the accepted answer.
  3. Alternative bitwise promoted by one of my colleagues which is a bit slower than second algorithm but returns quadrants in correct order.

所有的算法都得到了优化,以便采用双重计算点。

业绩测试向我们显示,一般而言,第一种分支算法是MacOS的获奖者。 X,虽然在六氯环己烷机器上,我们确实看到第二算法比分管更快。

www.un.org/Depts/DGACM/index_spanish.htm 因此,一般结论是坚持分行算法,因为双向版本没有带来任何业绩收益。

我的第一项尝试是取消附加条件。

int xi = p.X >= Center.X ? 1 : 0;
int yi = p.Y >= Center.Y ? 2 : 0;
int quadrants[4] = { ... };
return quadrants[xi+yi];

如果允许重新编号,就可选择分数。 我的法典仍然需要两个比较,但可以同时进行。

我预先对通常采用C++的C#错误表示歉意。


如果两个未签名的31个轨道坐标储存在64个远距中,则可能更为有效。

// The following two lines are unnecessary
// if you store your coordinated in unsigned longs right away
unsigned long Pxy = (((unsigned long)P.x) << 32) + P.y;
unsigned long Centerxy = (((unsigned long)Center.x) << 32) + Center.y;

// This is the actual calculation, only 1 subtraction is needed.
// The or-ing with ones hast only to be done once for a repeated use of Centerxy.
unsigned long diff = (Centerxy|(1<<63)|(1<<31))-Pxy;
int quadrant = ((diff >> 62)&2) | ((diff >> 31)&1);

退步,可能有一个不同的解决办法。 不要安排您的数据结构分成四舍五入,而是分两方向。 相关网站http://en.wikipedia.org/wiki/Kd-tree” rel=“nofollow noretinger”>也这样做。 Kd-tree





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...