Sign in to follow this  
errorist

[.net] how to add an array to the end of another array?

Recommended Posts

Hi all, Can someone tell me how to add an array to the end of another array? - in any .net language or c++. I tried using System::Collection::ArrayList and System::Collection::ArrayList::AddRange() but it is too slow, I also tried copying from both arrays to a third array with System::Collection::Array::CopyTo() function but it is still slow. (third array size == array1->Count + array2->Count) I also tried using System::Buffer::BlockCopy() function and use it the same way I used System::Collection::Array::CopyTo(), it is a little faster than all previous tries. I looked at System::InteropServices::Marshal::Copy() but I am unable to use it in this problem. The strange thing is in all those previous tries, the rendering code loops 530 times to group the indices based on their face attribute ID and render ~5000 triangles but it is still slower than looping ~5000 times (num of tris) to group and render the level. (I use System::Collection::ArrayList::Add() function here) ArrayList::AddRange == ~20-30FPS for ~5000 faces Array::CopyTo == ~15-20FPS for ~5000 faces Buffer::BlockCopy == ~30FPS for ~5000 faces ArrayList::Add == ~50FPS for ~5000 faces If u know a fast way for adding an array to the end of another array with the same type, please tell. or should I just call DrawIndexPremitives() 530 times to render ~13500 faces? is it OK? thank you in advance.

Share this post


Link to post
Share on other sites
You probably won't find anything much faster than BlockCopy. You can use Marshal::Copy if you lock the arrays in managed memory first, but I doubt it would be faster. I can't remember the keyword to lock arrays in C++.NET - in C# it's fixed. I think it might be pin or something like that in C++.NET. (You probably have to toss a couple underscores in front of it.) I'm only to the fourth chapter in my Managed DirectX book, so I'm not sure about the answer to your second question :).

Share this post


Link to post
Share on other sites
I chose to redesign the data structures in my engine to prevent the need of copying arrays. Not only is copying expensive in time but it is also a memory issue.

Now I have several big arrays that do not resize and my 3D objects have an index offset and length in those buffers.

I designed to have several array so I can store 'equal' kinds of data in the same array. (same texture, same shader, 3D or 2D etc.)

Cheers

Share this post


Link to post
Share on other sites
A couple of things:

1. ernow's idea is probably the best. If you are using dotnet 2.0 look at the System.ArraySegemnt<T> structure.

2. Whe you construct an ArrayList (or mayn other of the dynamic types) you can specify an inital capicity. If the inital capicity is less than the sum of the length of your two arrays than it may have to re-alocate and copy the existing array, so if you can set this number to the correct final size or a somewhat bigger number.

3. similar to ernow's way of doing things you could implement IList with a class that holds an array of arrays offseting the item property by the sum of the lengths of the pervious arrays and setting the Count to the sum of the lengths of all the arrays. Another layer of inderiction, but should make it so you don't have to copy.

Share this post


Link to post
Share on other sites
Was just looking at MSDN .NET and there is a new free(?) collection library theyare distributing there called PowerCollections. Don't know if it is any good or not, but it contains a class BigList<T> that looks targeted at doing something like what you are doing.

Share this post


Link to post
Share on other sites
@TheBluMage:
i use VC8...and the keyword is pin_ptr...they got rid of underscores in VC8... :D

i know how to use Marshal::Copy...but the problem is that there is no parameter to tell the function the index in the target array where pasting should start...just like in Array::CopyTo...

@ernow:
u r right...i am going to redesign some parts...i need to...thanx alot for u replay... :)

@turnpast:
thanx for ur replay too...very usefull...i have downloaded the PowerCollection library...going to check it now...

Share this post


Link to post
Share on other sites
Quote:
Original post by errorist
i know how to use Marshal::Copy...but the problem is that there is no parameter to tell the function the index in the target array where pasting should start

Since Marshal::Copy operates on pointers, you'd have to add the index to the array pointer to get a pointer to the element in the array at which copying should begin. Again, I really doubt that this will give you any performance benifits (I would guess that it would be slower than BlockCopy). Looks like some of the gurus here have some good ideas on ways around the problem though, so I'll be quiet and let the smart guys take it from here.[lol] Good luck!

Share this post


Link to post
Share on other sites
well, I changed the design a little.

Instead of copying any array - I just write the array directly into my dynamic index buffer with a GraphicsStream object.

I get the pointer to GraphicsStream object for the index buffer when locking it.

I lock the Index buffer only once per frame.

There is one index buffer per texture group.

This new design speed is 30-35 fps for ~5000/~13000 faces...

still slow...but it is ok...i switched to the first try...looping through all faces in a visible node...and add it to the list if it is not added before...

i get 55-65 fps for ~5000/~13000 faces...

i will implement some occlusion culling now...i will use it on node's object bounding box to see if a node is visible or not...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this