Sign in to follow this  
PM-Heavy

C# array question

Recommended Posts

PM-Heavy    147
I'm trying to add next/previous buttons for my C# program to cycle through files in a directory. I'm using Directory.GetFiles() to return a string[]. I'd like to start from the file that is already opened, and not from the beginning of the directory. I can find the filename of the opened file, but is there anyway to find where it is in the array? Sorry if this question is hard to understand, this is my first time working with file I/O. Also, to avoid making another thread I'll ask this question now: my next project will be a game and because I'd like to learn more C# it will probably use XNA. I'm wondering if Game Studio 3 is free? I know that the Express one is, but the download for 3 doesn't say anything about paying to download it, but it doesn't say it's an express edition either. Thanks for any help with either question.

Share this post


Link to post
Share on other sites
Kuraitou    250
Use this function to get the index of a value from an array:

        private int GetValueIndex(object[] array, object value)
{
for (int index = 0; index < array.Length; index++)
{
if (array[index] == value)
return index;
}
}

Share this post


Link to post
Share on other sites
NickGravelyn    855
Quote:
Original post by PM-Heavy
Also, to avoid making another thread I'll ask this question now: my next project will be a game and because I'd like to learn more C# it will probably use XNA. I'm wondering if Game Studio 3 is free? I know that the Express one is, but the download for 3 doesn't say anything about paying to download it, but it doesn't say it's an express edition either.


There is only one XNA Game Studio (well, only one version per release, so there's only on XNA GS 2.0 and will only be one XNA GS 3.0). And it is free. "Express" was just attached to the first version because it only supported Visual C# 2005 Express. Now that XNA Game Studio works with all versions of Visual Studio, they've dropped the "Express" part of the name.

Share this post


Link to post
Share on other sites
Kuraitou    250
I'm not going to force my opinion, but I took the initiative to test the results between my loop method and Array.IndexOf.

(Using an array with 4096 elements) In 10,000 calls to either function, the loop took 0.188 seconds to execute, and the Array.IndexOf took 0.703 seconds. Similarly, with 50,000 calls, the loop took 0.937 seconds and Array.IndexOf took 3.531 seconds.

Here's the entire console application for those who are interested:

using System;
using System.Collections.Generic;
using System.Text;

namespace TestFunctions
{
class Program
{
public static int GetValueIndex(object[] array, object value)
{
for (int index = 0; index < array.Length; index++)
{
if (array[index] == value)
return index;
}
return -1;
}

static void Main(string[] args)
{
Random rng = new Random();
object[] o = new object[4096];

for (int i = 0; i < o.Length; i++)
{
o[i] = (object)rng.NextDouble();
}

int valueToTestFor = Convert.ToInt32(o[4000]);

int ss = DateTime.Now.Second;
int sm = DateTime.Now.Millisecond;

for (int n = 0; n < 10000; n++) // 10000 tests
{
GetValueIndex(o, (object)valueToTestFor);
}

int es = DateTime.Now.Second;
int em = DateTime.Now.Millisecond;

Console.WriteLine("[loop] Start:\t" + Convert.ToString(ss) + "." + Convert.ToString(sm));
Console.WriteLine("[loop] End:\t" + Convert.ToString(es) + "." + Convert.ToString(em));

ss = DateTime.Now.Second;
sm = DateTime.Now.Millisecond;

for (int n = 0; n < 10000; n++) // 10000 tests
{
Array.IndexOf(o, (object)valueToTestFor);
}

es = DateTime.Now.Second;
em = DateTime.Now.Millisecond;

Console.WriteLine("[array.indexof] Start:\t" + Convert.ToString(ss) + "." + Convert.ToString(sm));
Console.WriteLine("[array.indexof] End:\t" + Convert.ToString(es) + "." + Convert.ToString(em));

Console.Read();
}
}
}


Share this post


Link to post
Share on other sites
Telastyn    3777
Who cares?

You're using the wrong data structure for searching. At that point, you're using a bucket to bail out the titanic. 7x difference is kinda paltry.

I threw together a quick test:


class Program {
static void Main(string[] args) {
Dictionary<int, int> table = new Dictionary<int, int>();
List<int> list = new List<int>();
int[] arr = new int[100000];

for (int i = 0; i < 100000; ++i) {
arr[i] = i;
list.Add(i);
table.Add(i, i);
}

DateTime Tracker;


int rslt;
Random rng = new Random();

Tracker = DateTime.Now;
for (int i = 0; i < 100000; ++i) {
int key = rng.Next(100000);
if (table.ContainsKey(key)) {
rslt = table[rng.Next(100000)];
}
}
Console.WriteLine( DateTime.Now - Tracker);

Tracker = DateTime.Now;
for (int i = 0; i < 100000; ++i) {
rslt = list.IndexOf(rng.Next(100000));
}
Console.WriteLine(DateTime.Now - Tracker);

Tracker = DateTime.Now;
for (int i = 0; i < 100000; ++i) {
rslt = Array.IndexOf<int>(arr, rng.Next(100000));
}
Console.WriteLine(DateTime.Now - Tracker);
}
}



I used 100,000 elements because I couldn't get results with smaller values. It ran too fast.


Dictionary Search 0.05s
List IndexOf 20.63s
Array IndexOf 21.07s



Though this assumes that the 'find file in the list' is anywhere near the slowest part of your program, and there's no proof that the OP is suffering there. Indeed, I would be astounded if this one operation is a drop in the bucket compared to Directory.GetFiles()


Or to be brief: use the damned library.

Share this post


Link to post
Share on other sites
Mike.Popoloski    3258
Quote:
Original post by Kuraitou
I'm not going to force my opinion, but I took the initiative to test the results between my loop method and Array.IndexOf.

(Using an array with 4096 elements) In 10,000 calls to either function, the loop took 0.188 seconds to execute, and the Array.IndexOf took 0.703 seconds. Similarly, with 50,000 calls, the loop took 0.937 seconds and Array.IndexOf took 3.531 seconds.

Here's the entire console application for those who are interested:

*** Source Snippet Removed ***


I would expect your version to be faster, since the .NET version does checks to ensure that parameters are valid.

Second, your method uses objects, which ends up causing lots of boxing and unboxing, and if I want to test on an array of bools, I need to create a whole new method. The .NET makes use of generics to avoid this mess.

Third, the .NET method is more flexible, with overloads taking parameters to specify different portions of the array to operate on.

Fourth, and perhaps most egregiously, your method won't even actually work; it will always return -1. The operator == of the object class checks for reference equality, which in the case of value types will never be the same. You would need to use Equals to check for value equality.

Share this post


Link to post
Share on other sites
PM-Heavy    147
I decided to use the Array.IndexOf() method because the only reason I'm even writing this program at all is to learn C#/.NET. The program is just meant to be an easy way to add metadata to JPEGs. I thought is would be a fairly simple way to get used to C# before using XNA.

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