XNA Creators Club Online
Page 1 of 1 (7 items)
Sort Posts: Previous Next

Function parameters value/reference - need value, but only have reference?

Last post 4/29/2008 1:24 PM by ShawMishrak. 6 replies.
  • 4/29/2008 10:42 AM

    Function parameters value/reference - need value, but only have reference?

    Hello!

    I need to create a preview of my changed 2D-Array. So I wrote this function here:
            public static int[,] PreviewBoard(int[,] board, Point start, Point end)
    {
    int[,] result = new int[8, 8];

    result = board;

    result[end.X, end.Y] = result[start.X, start.Y];
    result[start.X, start.Y] = 0;

    return result;
    }
    But it will result in a change of the original "board"-variable passed in. I also tried doing it just by editing the board, but it always takes it as reference and so modifies my original, which I don't want because it should only be a preview.
    I don't see a way to use board.CopyTo() because it only works for 1D-Arrays and C# won't allow me to access a sub-array of the board by using board[0] or something.

    So what the heck could I do that only the copy is modified?

    And looping through all the board-ints and passing them into the result-matrix is not suitable since it is time-critical.
    MMORPG Engine and Game |My Blog |Lennart Moltrecht's Website
    There are 10 kinds of people: Those who understand binary encoding and those who don't.
  • 4/29/2008 11:04 AM In reply to

    Re: Function parameters value/reference - need value, but only have reference?

    You would be okay with CopyTo() but not directly copying the array yourself?  What do you think CopyTo() would do internally?  I don't see any way to do this without generating a copy, and C# itself doesn't provide much in the way of efficient array copying, especially multi-dimensional arrays.

    You could always pull the memcpy trick, and then it would be as fast as your C Runtime's memcpy implementation (plus managed -> native -> managed overhead).  The example below shows using memcpy to copy an entire array.  As long as the array size is sufficiently large, it should be faster than doing an element-by-element copy.

    int[,] myArray = new int[8, 8];
    int[,] copy = new int[8, 8];

    for(int i = 0; i < myArray.GetLength(0); ++i)
    {
    for(int j = 0; j < myArray.GetLength(1); ++j)
    {
    myArray[i, j] = i + j;
    }
    }

    fixed(int* src = &myArray[0, 0])
    {
    fixed(int* dest = &copy[0, 0])
    {
    memcpy((IntPtr)dest, (IntPtr)src, myArray.GetLength(0) * myArray.GetLength(1) * sizeof(int));
    }
    }

    Then you'll need to reference msvcrt.dll:

    [DllImport("msvcrt.dll")]
    private static extern IntPtr memcpy(IntPtr dest, IntPtr src, long size);

    Of course this won't work on Xbox.
    Microsoft DirectX/XNA MVP
  • 4/29/2008 11:19 AM In reply to

    Re: Function parameters value/reference - need value, but only have reference?

    Lennart Moltrecht:

    So what the heck could I do that only the copy is modified?

    Your problem is, that you don't actually have a copy, so there is no way that only the copy can be modified. What you have is one single array, and two different variables referencing that same array ("board" and "result"). Doing "result = board;" as you do does not create an actual copy, but simply makes "result" a second reference to the same array that is already referenced by "board". This is the same for 1D as for 2D arrays, which is why there is a board.CopyTo() method for 1D arrays in the first place. And this CopyTo() method simply does a loop over the original array and copies everything to the other array too, so this:

    Lennart Moltrecht:

    And looping through all the board-ints and passing them into the result-matrix is not suitable since it is time-critical.

    is probably the only solution that you have. However, I don't think that making a copy of an 8x8 array, with 64 fields, where then only 2 of these 64 fields are actually changed for the preview, is a good idea to begin with. I would take a good look at the other code (where you want to call "PreviewBoard") and try to think of a solution to achieve the same goal as you currently try to achieve with the preview copy, only in a different way. You need to remember, that even if you had an efficient way of creating the array copy, it would still create a lot of garbage, which is also not a good idea in a time-critical loop.

    Doc

    Urgently needed: Reviews in German for Kuchibi and Golden Tangram (No more reviews in English needed :-)

    Twitter - My Game Trailers - www.spyn-doctor.de - Games: Your Doodles Are Bugged! - Kuchibi - Golden Tangram

    Useful for peer reviews and testing your own game: My little "evil" checklist for peer review stress testing
  • 4/29/2008 11:27 AM In reply to

    Re: Function parameters value/reference - need value, but only have reference?

    Ok thanks for the answers, at least I learned something. I do it now by just copying the array manually, and all my code together (the whole checkmate stuff for the game) takes 3ms if the board is completely filled with figures and 0ms when only a few are left, so there shouldn't be a problem with that at all :D
    (I'm impressed, around 1000 loops, creating of lists, ... in 3ms.. and I beat my friend by miles, he tried to achieve the same, his code needs 800ms :D)
    MMORPG Engine and Game |My Blog |Lennart Moltrecht's Website
    There are 10 kinds of people: Those who understand binary encoding and those who don't.
  • 4/29/2008 11:30 AM In reply to

    Re: Function parameters value/reference - need value, but only have reference?

    There will only be garbage if you new up an aray every time.

    So just make a new staic variable called PreviewCopy and copy the array into it.

    Seriously a 8x8 nested loop with 64 int assignments isn't going to be on your critical path no matter what game you are writing. Worry about performance when your profiler tells you to.

     

    Play Kissy Poo - a game for 4 year olds on Xbox and windows
    The ZBuffer
    News and information for XNA
      Follow The Zman on twitter, Email me
        Please read the forum FAQs - Bug/Feature reporting
          Don't forget to mark good answers and good playtest feedback when you see it!!!
  • 4/29/2008 12:29 PM In reply to

    Re: Function parameters value/reference - need value, but only have reference?

    It would be easier and probably also faster to use Array.Clone for this.
    XNA Framework Developer - blog - homepage
  • 4/29/2008 1:24 PM In reply to

    Re: Function parameters value/reference - need value, but only have reference?

    Shawn Hargreaves:
    It would be easier and probably also faster to use Array.Clone for this.


    This is entirely dependent on the size of the array.  The overhead from nested method calls, some of them virtual, can make Array.Clone perform worse than direct element-by-element copying.  For tiny arrays such as 8x8 arrays, the overhead of Clone is nearly three times that of just doing an element-by-element copy, not to mention creating garbage since you cannot just use a static array instance with Clone.  For a single instance this is not a big deal, but it's good to keep in mind if you do a lot of transforms on small arrays.

    For large arrays, Clone is definitely a win because it can optimize somewhat the memory copying, though just interop'ing to memcpy with fixed array pointers will be faster for sufficiently sized arrays.  In my experience, memcpy is faster once you start getting into "huge" arrays, around 400-500 elements in at least 2 dimensions.  Of course you'll want to be careful if you're using non-primitive types in the array.
    Microsoft DirectX/XNA MVP
Page 1 of 1 (7 items) Previous Next