Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

string to int's


  • Please log in to reply
8 replies to this topic

#1 gordon128

gordon128

    New Member

  • Members
  • Pip
  • 9 posts

Posted 06 June 2011 - 05:27 PM

I want to take a string that has a series on numbers separated by commas, like: string mystring = "1234,34,26,6,1,0"; and extract those numbers into a number of integers, like: int a, int b, int c, int d, int e, int f ....etc. or into an array -> int[1 to x] numbers; Can any one give an example of possible code? Regards Gordon

#2 Nevyn

Nevyn

    Advanced Member

  • Members
  • PipPipPip
  • 1072 posts
  • LocationNorth Yorkshire, UK

Posted 06 June 2011 - 06:04 PM

I want to take a string that has a series on numbers separated by commas,

like: string mystring = "1234,34,26,6,1,0";

and extract those numbers into a number of integers,

like: int a, int b, int c, int d, int e, int f ....etc.

or into an array -> int[1 to x] numbers;

Can any one give an example of possible code?


Try:

string mystring = "1234,34,26,6,1,0";
string[] numbersAsStrings = mystring.Split(',');
int[] numberAsInts = new int[numbersAsStrings.Length];
for (int index = 0; index < numbersAsStrings.Length; index++)
{
    numberAsInts[index] = int.Parse(numbersAsStrings[index]);
}

Would not expect too much in the way of performance though - there are two expensive operations there, the Split and the Parse.

Regards,
Mark

To be or not to be = 0xFF

 

Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life

Follow @nevynuk on Twitter


#3 gordon128

gordon128

    New Member

  • Members
  • Pip
  • 9 posts

Posted 06 June 2011 - 06:59 PM

Try:

string mystring = "1234,34,26,6,1,0";
string[] numbersAsStrings = mystring.Split(',');
int[] numberAsInts = new int[numbersAsStrings.Length];
for (int index = 0; index < numbersAsStrings.Length; index++)
{
    numberAsInts[index] = int.Parse(numbersAsStrings[index]);
}

Would not expect too much in the way of performance though - there are two expensive operations there, the Split and the Parse.

Regards,
Mark




Mark,

Your a star - cheers!

That does the job perfectly.
This is one big learning curve!

Thanks again for your help.

Regards Gordon.

#4 Mati

Mati

    New Member

  • Members
  • Pip
  • 9 posts
  • LocationIsrael

Posted 06 June 2011 - 08:51 PM


Would not expect too much in the way of performance though - there are two expensive operations there, the Split and the Parse.


Well, I was bored. Here's an alternative ugly way to do this without using Split and Parse. Probably faster though.


            string mystring = "1234,34,26,6,1,205";

            // An array list allows easy management of it items, especially when you 
            // don't know their type or initial amount
            ArrayList numList = new ArrayList();

            // Assign a variable to store the sum for the current number
            int currSum = 0;

            // Run over each character in the string plus one extra for the tailing digit
            // (there are a lot of ways of handling the last digit, I chose this one)
            for (int i = 0; i < mystring.Length + 1; i++)
            {
                // Check that we didn't reached a comma (which means move to next number) OR
                // that it isn't the last digit.
                if (i != mystring.Length && mystring[i] != ',')
                {
                    // Multiply the current sum by ten to add the digit into it's right place.
                    // (For the first digit of each number, this multiplication is useless)
                    currSum *= 10;

                    // Add the current digit - subtract 48 to convert the ASCII char to number
                    currSum += (int)mystring[i] - 48;
                }
                else
                {
                    // We have reached a ',' or the last char - add the current sum
                    numList.Add(currSum);

                    // Reset the current sum to handle the next number
                    currSum = 0;
                }
            }


I would recommend you Mark's way. That's how I would implement it too normally. But if you are bored like me or
very performance greedy, you can do it my way too :). This one can be optimized even more (I'm not that bored)
Windows XP SP3, Q6600.

#5 Inquisitor

Inquisitor

    Advanced Member

  • Members
  • PipPipPip
  • 91 posts
  • LocationAtlanta, Georgia, USA

Posted 20 July 2011 - 11:27 PM

Well, I was bored. Here's an alternative ugly way to do this without using Split and Parse. Probably faster though.


Mati,

Have you or anyone else bench marked these two versions? The reason I ask... I'm new and awaiting my N+ and have too much time on my hand waiting. I read that the .NET on Netduino is interpreted and not JIT compiled like larger machines. However, I would assume all the .NET code would be precompiled. If so, I would think the Split/Parse methods would have an advantage over rolling our own substitutes. But, I'd be curious which assumption is correct.

Thanks!
Doing my best to keep the smoke in the little black boxes.
If my message helped you... how 'bout giving me a Posted Image
www.MessingWithReality.com

#6 grjonib

grjonib

    New Member

  • Members
  • Pip
  • 2 posts

Posted 21 July 2011 - 06:43 PM

Mati,

Have you or anyone else bench marked these two versions? The reason I ask... I'm new and awaiting my N+ and have too much time on my hand waiting. I read that the .NET on Netduino is interpreted and not JIT compiled like larger machines. However, I would assume all the .NET code would be precompiled. If so, I would think the Split/Parse methods would have an advantage over rolling our own substitutes. But, I'd be curious which assumption is correct.

Thanks!


I did a simple test where I run both methods 1000 times and this is what my netduino plus shows:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Time using Split and Parse: 13621 [ms]
Time not using Split and Parse: 18837 [ms]
The thread '<No Name>' (0x1) has exited with code 0 (0x0).
Done.

Only when using single digit ints was the split and parse method slower ( by a small margin )

Here is the code I used:

using System.Diagnostics;
using Microsoft.SPOT;
using System.Collections;

namespace NetduinoStringTest
{
    public class Program
    {
        public static void Main()
        {
            // write your code here

            string mystring = "1234,34,26,6,1,0,1234,34,26,6,1,205";
            //string mystring = "1,4,2,6,1,0,1,3,2,6,1,2";
            //string mystring = "412131,357845,267536,456767,123458,254390,214547,324546,224315,613784,142133,123422";
            ArrayList myAL = new ArrayList();

            int length = 1000;

            Stopwatch sw1 = Stopwatch.StartNew();
            for (int i = 0; i < length; i++)
            {
                myAL = String1(mystring);
            }
            sw1.Stop();

            Stopwatch sw2 = Stopwatch.StartNew();
            for (int i = 0; i < length; i++)
            {
                myAL = String2(mystring);
            }
            sw2.Stop();

            Debug.Print("Time using Split and Parse: " + sw1.ElapsedMilliseconds + " [ms]");
            Debug.Print("Time not using Split and Parse: " + sw2.ElapsedMilliseconds + " [ms]");
        }

        public static ArrayList String1(string mystring)
        {

            string[] numbersAsStrings = mystring.Split(',');
            ArrayList numberAsInts = new ArrayList();
            for (int index = 0; index < numbersAsStrings.Length; index++)
            {
                numberAsInts.Add(int.Parse(numbersAsStrings[index]));
            }

            return numberAsInts;
        }

        public static ArrayList String2(string mystring)
        {
            ArrayList numList = new ArrayList();
            int currSum = 0;
            for (int i = 0; i < mystring.Length + 1; i++)
            {
                if (i != mystring.Length && mystring[i] != ',')
                {
                    currSum *= 10;
                    currSum += (int)mystring[i] - 48;
                }
                else
                {
                    numList.Add(currSum);
                    currSum = 0;
                }
            }

            return numList;
        }


    }
}


#7 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 23 July 2011 - 06:52 PM

I did a simple test where I run both methods 1000 times and this is what my netduino plus shows:
Time using Split and Parse: 13621 [ms]
Time not using Split and Parse: 18837 [ms]
The thread '<No Name>' (0x1) has exited with code 0 (0x0).

Only when using single digit ints was the split and parse method slower ( by a small margin )


This benchmark isn't really definitive because String2 isn't written as tightly as it could be. If we do some optimizations (which wouldn't matter in the full .NET framework, but appear to matter a lot in the Micro Framework), we get the following routine which beats the pants off of both your String1 and String2:

    public static ArrayList String3(string mystring) {
      var numList=new ArrayList();
      var currSum=0;
      var length=mystring.Length;
      for(var i=0; i<length; i++) {
        var ch=mystring[i];
        if(ch!=',') {
          currSum=currSum*10+(ch-48);
        } else {
          numList.Add(currSum);
          currSum=0;
        }
      }
      numList.Add(currSum);
      return numList;
    }

I used Utility.GetMachineTime because I don't know where Stopwatch lives. My timings:

Time using Split and Parse: 00:00:13.2957654
Time not using Split and Parse: 00:00:17.6939520
improved code (not using Split and Parse): 00:00:07.9082027

#8 grjonib

grjonib

    New Member

  • Members
  • Pip
  • 2 posts

Posted 25 July 2011 - 06:03 PM

Interesting. Can anyone explain this? Is there someplace you can read about best practices for the micro framework or is it just gut-feeling you get with experience? regards, grjonib NOOB

#9 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 25 July 2011 - 07:20 PM

Well for me it was a matter of realizing that the C# compiler only does relatively few optimizations, leaving the more aggressive ones to be done by the runtime. And then knowing that the Micro Framework doesn't have much of a runtime, so it isn't going to be doing any optimization either. So I could see that in your code, every time through the loop you were reading the .Length property twice, comparing against it twice, and subscripting the array twice. I suspected that changing all of those to "once" would help, and then I further suspected that hoisting the read of .Length out of the loop altogether would make it go even faster. On the full framework, one might consider optimizations like that premature. But the performance penalties of the Micro Framework are a lot more severe.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.