简体   繁体   中英

c# array looping bitwise index vs null checking

In my project I am working with an array of objects(object[]) of a user decided length. It is also looped through at least a couple hundred times a second in the course of the application. This array also has a class associated with it that assures that any additions to it will fill the first open spot using an array that has a bit set for each occupied element. Once assigned array entries stay where they are as it would effect tracking of the elements to move them so gaps are possible.The number of elements that may be removed or added is unknown. Addition and removal happen much less frequently than the elements are looped through and accessed.

What I need to know is which would provide better average performance when looping though this array...

  1. Check each entry for null

or

  1. Call the following code to get the next index in a loop checking for the -1 to stop. Tracker contains the bitwise locations of the elements. The function only needs to run once per filled element. The &= line and the subtraction on the following line yields the integer value of the lowest bit set. The DeBruijn sequence bit performs a log base 2 to get the bit position.

     private List<Int32> Tracker = new List<Int32>(); private int EnumTemp; private int EnumTemp2; private int EnumResult; private int EnumIndex = -1; //from http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn protected internal static readonly Int32[] MultiplyDeBruijnBitPosition2 = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; public int NextIndex() { if (EnumIndex == -1) { EnumTemp = Tracker[0]; EnumIndex = 0; } while (EnumTemp == 0) { if (EnumIndex == Tracker.Count -1) { EnumIndex = -1; return -1; } EnumIndex++; EnumTemp = Tracker[EnumIndex]; } EnumTemp2 &= EnumTemp - 1; EnumResult = Engine.MultiplyDeBruijnBitPosition2[(UInt32)((EnumTemp-EnumTemp2) * 0x077CB531U) >> 27]; EnumResult += (EnumIndex * 32); EnumTemp = EnumTemp2; return EnumResult; } } 

    Assume the the array element will be accessed and stored in a temporary variable in both cases.

There is a point where the speed of checking x null-rows for null will be slower as quickstepping with the tracker. You need to have some idea of how large the gaps will be. But my gut feeling says there should be pretty large gaps (say 5 times more empty rows as filled rows) before this will help. As for why I think this;

  • Array access is sequentially and perfectly prefetched. So the first y entries after a filled one are in cache already. Skipping them will not prevent memory accesses

  • Null checks are very fast. The tracker is 'complex' when compared to that

  • Your code becomes much more complex for possible very little gain.

  • I think a doublylinkedlist might be faster in your case as it will feature no gaps at all and can be looped through efficiently. You do not need the spot in the array then as you can remove the object using the linkedlistreference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM