0

I have a rather strange problem that I cannot figure out. I am using a third party library that creates a buffer. This buffer can contain doubles but copying between a double array and it is extremely slow. There must be something going on behind the scenes with the particular data type, specifically when you write to it. For example, the following works but take over 20 ms whereas a copy from a double array to another double array takes 20us.

Mitov.SignalLab.RealBuffer mitovBuffer = new Mitov.SignalLab.RealBuffer(16384);
double[] doubleBuffer = new double[16384];

private void Test()
{
    for (int i=0; i < 16384; i++)
    {
         mitovBuffer[i] = doubleBuffer[i];
    }
}

This works but takes 20+ ms. I can get a pointer to the mitovBuffer and I know that there are 8 bytes stored for each "double" in this buffer. Is there a way I can copy between these two? I've tried all the usual things like array.copy, block copies etc. Each time I get a cannot convert from a "double[] to double" error. Thanks, Tom

Tom
  • 527
  • 1
  • 8
  • 28
  • Hi Tom. It would be easier if you were able to show how `RealBuffer` is defined. – MarcinJuraszek Oct 07 '18 at 23:19
  • Use `Blockcopy` `Array.Copy` or p/invoke `memcpy`, then performance test them for your own needs, unsafe will be `faster`, then a direct element copy, however with larger arrays one of the bulk copy methods with be faster – TheGeneral Oct 07 '18 at 23:20
  • Hi, yes I understand that but I not know how it is defined. – Tom Oct 08 '18 at 00:04
  • Blockcopy and Array.Copy do not work. error is as stated above. – Tom Oct 08 '18 at 00:04
  • If you dont have the definition of `RealBuffer` we cant help you with a bulk version, who knows what implicit stuff it has going on and what it is doing to convert itself. Until you get that or decompile it, or know how the memory is stored byte/bit wise your only option is to what you are doing – TheGeneral Oct 08 '18 at 00:16

1 Answers1

4

Perhaps one reason this function is slow is because Mitov.SignalLab.RealBuffer is a wrapper around a resizeable delphi buffer. If I understand their documentation correctly, the byte-wise assignment you are doing involves layers of abstraction that might even involve resizing the buffer for every byte.

The API even says that the class is intended for use within Delphi code, not from other languages. The API says

This is Real(double) Data wrapper buffer. Use this buffer to access and manipulate the Real(double) data from inside your Delphi code. .NET, C++ Builder and Visual C++ users should use the much more convenient and powerful TSLCRealBuffer class.

However, their public API does not document that recommended class. Perhaps the documentation doesn't really reflect the product, but if I were you I'd call their engineers to find out what you are intended to do. Since you won't be able to pin their "buffer" abstraction, I suspect you don't want to use unmanaged code to push bytes into those locations.

If you want to try byte-wise loading, perhaps you might try their documented bytewise methods:

function GetByteSize() : Cardinal - Returns the size of the buffer in bytes.
function GetSize() : Cardinal - Returns the size of the buffer in elements.
function ByteRead() : PByte
function ByteWrite() : PByte
function ByteModify() : PByte

Or perhaps you can put your data into their internal format and then call their public procedure procedure AddCustom(AData : ISLData)

Craig.Feied
  • 2,617
  • 2
  • 16
  • 25
  • Thanks Craig. I did look for the TSLCRealBuffer and it was nowhere to be found! – Tom Oct 10 '18 at 16:41