Search Unity

Performance critical byte[] cut

Discussion in 'Scripting' started by JackS1001, May 5, 2021.

  1. JackS1001

    JackS1001

    Joined:
    Mar 12, 2021
    Posts:
    16
    Hello.

    I have an ArraySegment from which I'm trying to read the data from.

    I need to skip first two bytes, and read the amount of bytes in an array for the number of positions contained in another variable. In order to extract a string I would need to use:
    Code (CSharp):
    1. BitConverter.ToString(data.Array, data.Offset + 2, data.Count);
    But how do I get the byte[] instead of string? How do I get data.Count amount of bytes only after data.Offset + 2?

    This is in extremely performance critical context.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Bunny83 likes this.
  3. JackS1001

    JackS1001

    Joined:
    Mar 12, 2021
    Posts:
    16
    The link you provided provides solution to a question that BitConverter solves as well. But that's the thing, I don't need a string, I want to extract byte[] starting from
    data.Offset + 2
    as index for
    data.Count
    positions.

    I thought about using Skip(2) but this converts it to IEnumerator and it might hit performance. After which I'm still left with a problem with limiting it to
    data.Count
    positions. I realize that there's
    array.Skip(2).Take(10).ToArray();
    but that still involves casting.

    From:
    00 00 10 10 10 10 10 10 00 00 00 00
    With data.Offset + 2
    and data.Count == 6.
    I somehow need to end up with an array:
    10 10 10 10 10 10

    I meant that this isn't once-every-10-seconds code so I can't use super complex functions and need to avoid senseless but easy boxing and advanced libraries.
     
    Last edited: May 5, 2021
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Use Array.Copy.
     
    JackS1001 likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Yes, this... this exactly, or more specifically,

    Once Uncle Kurt AND Uncle Joe have both suggested something, man, that something is really a something!

    Seriously, make a new array smaller in size by 2, copy it over with the above. I thought you actually WANTED a string out of it.
     
    Joe-Censored, JackS1001 and Bunny83 like this.
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,990
    Like others have said, using System.Array.Copy is the fastest solution because (as far as i know) under the hood it's actually implemented in native unsafe code and does a direct memory copy.

    However I'm just wondering "why" you actually need that data as a seperate byte array. If performance is critical it's usually best to just use the data in place and just pass the offset and count along. That's what is actually the norm in the C / C++ world unless you use some convenient wrapper type.

    Recently I've written a C# tool (not Unity related at all) that actually reads a huge chunk of screen memory using System.Drawing.Graphics. I actually process the data in an unsafe section by using some pointer magic. However I copied the relevant sections into ordinary managed arrays in a for loop for later processing. I did a lot of post processing on the image data, convert it to monochrome and then compare parts of the screen to saved images in order to identify the part. The area I copied on my resolution covered an area of about 180k pixels. I ran this in an ordinary WinForms application on an ordinary timer and get an update rate of almost 60 fps. Computers are blazing fast nowadays. So I'm wondering where and how you use that data and how much data we actually talk about. If performance is critical you of course want to avoid recreating those arrays all the time if possible.

    (ps: If you want to know what that C# tool was about, it's essentially a "hacking tool" for the virtual "hacking tool" in GTA online for the casino heist :) I generally don't like cheating in games. However since this essentially is supposed to simulate "hacking" into the door lock I think that was kinda appropriate ^^ It's also quite annoying. Though it just saves a bit of time. Actually my friend and I did the heist so many times we are already very quick manually, usually under 20 sec. per fingerprint. Though the tool will identify the right pieces (and wrong pieces) 60 times per second and selects the right ones within 1.5 seconds :p)