Handling a large amount of similar structures

I’m developing a library where I would like to use structures instead of pointers or classes. Pointers are fast, but there is no type-safety. Classes offer type-safety but slow things down too much in this case as tests have shown.

There are 68 pre-defined structures and the possibility for the developer using this library to add additional structure definitions (internally simulated via memory blocks). All structures have as first field a Ptr followed by more fields which are different for each of the structures.

There is only one function in a module using these structures. One of the parameters is an array types as either Variant or Auto. In this method, I must now explicitly cast the argument, be it a Variant or a Auto. It means I would have a Select Case statement with 68 + 1 branches. The 1 being for the structures registered by the user of the library. And he would have to provide a cast method for each of his registered structures.

Is there any way to get hold of the pointer to a structure or alternatively the first field in the structure (which is a pointer), when the structure is stored in a Variant or Auto – without casting.


In my experience, Variants are pretty slow, too : I wonder whether using Variants + Structures would end up being any faster than using Classes or not?

Can you say more about these 68 objects? What are they, how many are there? Perhaps there are other ways to speed things up…

Thanks Michael. The code is fast enough with structures instead of classes, so that’s not the problem.

Here is an example:

[code]Structure S1
Field1 As Ptr
… // more fields

Structure S2
Field1 As Ptr
… // more fields

Structure S3
Field1 As Ptr
… // more fields

// all structures up to S68 have a pointer as first field.

Structure S68
Field1 As Ptr
… // more fields

Function DoSomething(argument As Auto) // or argument As Variant
Dim p As Ptr
Select Case xojo.Introspection.GetType(argument).Name
Case “S1”
p = CType(argument, S1).Field1
Case “S2”
p = CType(argument, S2).Field1
Case “S3”
p = CType(argument, S3).Field1

Case “S68”
p = CType(argument, S68).Field1
// now do something with p

I would like to shorten the Select Case statement, as all 68 structures have a first field which is a pointer and I need that only. If one only could do something like this:

Dim mb As New Xojo.Core.MemoryBlock(aStructure)

You could use the ByteValue method to get the bytes and then the first index should be your pointer - I think. I haven’t tested it but I think that might be what you are looking for.

Dim mb As New Xojo.Core.MemoryBlock(aStructure.ByteValue())

Sorry, I should written this that way:

Dim mb As New Xojo.Core.MemoryBlock(anAutoOrVariantHoldingAStructure)

select case with ctype and its not easily user extensible if a user adds a structure etc

or write a loop to pull out all the bytes stuff them into a byte array & create the memory block from that

both of which are likely to slow your code down enough to make using a class worthwhile

and you lose everything else thats useful about classes

sounds like you’re trying to implement polymorphism on your own

Classes are way too slow in this case as 10.000 of these elements are created per second. I have already re-written the application to make it faster. It now is (drastically) faster. With the use of structures.

Now the code in this one function – and there is only one function – is over 2400 lines of code. If I could get rid of all these Select Case – casts, I would end up with only 200 to 300 lines of code. Which I would prefer of course…

I understand that the conversion AutoContainingAStructure to MemoryBlock is not possible when I read the docs as Auto requires explicit casting, but I have had the hope that someone maybe knew a stunt to convert VariantContainingAStructure to MemoryBlock (without casting to the specific structure type).

hmmm … can easily create 10000 class instances even in the debugger in well under a second (2377 microseconds)
now if they run slow constructors etc thats a different problem

I don’t understand why this would shorten your function, unless … there is a great deal of overlap / similarity between the 68 structures. If so, then I think you’d want to take another approach consisting of a “base class” and then structures that “inherit” from it, e.g.

Structure BASE {
    Field1 as Ptr

Structure S1{
   myBase as BASE
   other stuff ...

For this to work:

  • structures must be able to include other structures
  • you need to be able to treat a pointer to one structure like another.

I’m not sure if either of those are true in Xojo

Also, I tend to agree with Norman here : classes are not inherently slow - but it really depends on how you are managing the 10000 instance objects. Arrays? Dictionary? Linked list? BTree ? etc.