This question already has answers here:
Calculate the execution time of a method
(8 answers)
Closed 5 years ago.
I want to calculate execution time in a specific part of View in MVC asp.net
for example
<p>start time is A</p>
<br />
#for (int i = 0; i < 1000000; i++)
{
if (#i % 100000 == 0)
{
<p>#i</p> <br />
}
}
<p>End time is B</p>
<p>execution time is: C</p>
how to calculate A, B, C in above code ?
What I would recommend you to do here is to create an instance of Stopwatch by Stopwatch.StartNew, execute your method or your code that you want to calculate execution time. Stop the Stopwatch where you think you method should be done with execution, and then get ElapsedMilliseconds like I will do in code below:
#{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++)
{
if (i % 100000 == 0)
{
#Html.Raw("<p>" + i.ToString() + "</p> <br />");
}
}
stopwatch.Stop();
#Html.Raw("<p>Elapsed time is: " + stopwatch.ElapsedMilliseconds.ToString() + "</p>");
}
And please, in case you might get an Error while you are trying to execute this code, be sure that you've included System.Diagnostics;
P.S If you don't like stopwatch.ElapsedMilliseconds you might check also for stopwatch.Elapsed to display elapsed time..
As I can see after Alexander's comment that you want start time, end time etc, what I suggest you to do here is to create a custom Stopwatch by inheriting System.Diagnostics.Stopwatchclass and extending it with a couple of DateTime properties.
And I will now show you how you might do it:
public class MyCustomStopWatch : Stopwatch
{
public DateTime? StartAt { get; private set; }
public DateTime? EndAt { get; private set; }
public void Reset()
{
StartAt = null;
EndAt = null;
base.Reset();
}
public void Restart()
{
StartAt = DateTime.Now;
EndAt = null;
base.Restart();
}
//This is what is important to you right now, to get data about that when you code started, and when your code finished with executing
public void Start()
{
StartAt = DateTime.Now;
base.Start();
}
public void Stop()
{
EndAt = DateTime.Now;
base.Stop();
}
}
If you are wondering HOW COULD I USE THAT CODE?
DON'T WORRY, HERE IS AN EXAMPLE BASED ON YOUR QUESTION:
#{
MyCustomStopwatch stopwatch = MyCustomStopwatch();
for (int i = 0; i < 1000000; i++)
{
if (i % 100000 == 0)
{
#Html.Raw("<p>" + i.ToString() + "</p> <br />");
}
}
stopwatch.Stop();
#Html.Raw(String.Format("<p>Stopwatch elapsed: {0}, StartAt: {1}, EndAt: {2} </p>", stopwatch.ElapsedMilliseconds.ToString(), stopwatch.StartAt.Value.ToString(), stopwatch.EndAt.Value.ToString());
}
Whatever I hope that you catch up the point and I hope that this helped you to solve your problem
You can do it like this:
#{
DateTime StartTime = DateTime.Now;
System.Diagnostics.StopWatch Watch = new System.Diagnostics.StopWatch();
#Html.Raw("<p>start time is: " + StartTime.ToString() + "</p>");
Watch.Start();
for (int i = 0; i < 1000000; i++)
{
if (i % 100000 == 0)
{
#Html.Raw("<p>" + i.ToString() + "i</p> <br />");
}
}
Watch.Stop();
DateTime EndTime = DateTime.Now;
#Html.Raw("<p>End time is " + EndTime.ToString() + "</p>");
#Html.Raw("<p>Execution time is: " + Watch.Elapsed.ToString() + "</p>");
}
Normally, I would recommend using a StopWatch to track the elapsed time but since you want the start and end times you might as well captured two dates and display the difference to calculate the time span.
Related
I have to prepare Logger class which will be saving data from 3 structs in interval of 10-15 ms. My approach to this problem is below:
public class Logger
{
// Variables
private Task loggerTask;
public bool IsActive { get; set; }
// Constructor
public Logger()
{
}
private void Logging()
{
#if DEBUG
System.Diagnostics.Debug.WriteLine("Logging has been started.");
#endif
FileStream fs = new FileStream($"./log {DateTime.Now.ToString("dd.MM HH.mm.ss")}.txt", FileMode.Create, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
try
{
Queue<double> times = new Queue<double>();
Queue<Attitude> attitudes = new Queue<Attitude>();
Queue<LocalPositionNed> positions = new Queue<LocalPositionNed>();
Queue<SetPositionTargetLocalNed> setpoints = new Queue<SetPositionTargetLocalNed>();
// Logs data
DateTime start = DateTime.Now;
DateTime last = start;
DateTime now;
while (IsActive)
{
now = DateTime.Now;
if ((now - last).TotalMilliseconds < 16)
continue;
last = now;
times.Enqueue((now - start).TotalMilliseconds);
attitudes.Enqueue(GCS.Instance.Drone.Attitude);
positions.Enqueue(GCS.Instance.Drone.LocalPositionNed);
setpoints.Enqueue(GCS.Instance.Offboard.SetPoint);
}
// Save data
for(int i = 0; i < times.Count; i++)
{
sw.WriteLine($"{times.ElementAt(i)}\t" +
$"{attitudes.ElementAt(i).Pitch}\t" +
$"{attitudes.ElementAt(i).Roll}\t" +
$"{attitudes.ElementAt(i).Yaw}\t" +
$"{attitudes.ElementAt(i).Pitchspeed}\t" +
$"{attitudes.ElementAt(i).Rollspeed}\t" +
$"{attitudes.ElementAt(i).Yawspeed}\t" +
$"{positions.ElementAt(i).X}\t" +
$"{positions.ElementAt(i).Y}\t" +
$"{positions.ElementAt(i).Z}\t" +
$"{positions.ElementAt(i).Vx}\t" +
$"{positions.ElementAt(i).Vy}\t" +
$"{positions.ElementAt(i).Vz}\t" +
$"{setpoints.ElementAt(i).Vx}\t" +
$"{setpoints.ElementAt(i).Vy}\t" +
$"{setpoints.ElementAt(i).Vz}\t");
}
}
catch (Exception ex)
{
#if DEBUG
System.Diagnostics.Debug.WriteLine($"Logging exception: {ex.Message}");
#endif
}
finally
{
sw.Dispose();
fs.Dispose();
}
#if DEBUG
System.Diagnostics.Debug.WriteLine("Logging has been ended.");
#endif
}
// Static method
public void Start()
{
IsActive = true;
loggerTask = new Task(Logging);
loggerTask.Start();
}
public void Stop()
{
IsActive = false;
}
}
I have problem with intervals, because they are varying about 5-8 ms. My project requires maximum varying of 1-2 ms. Does anyone have idea how I can improve my approach.
Thank you for your responses.
The biggest issue is probably using DateTime.Now, this has poor resolution and is not appropriate for this kind of task.
A simple alternative that would be more appropriate is a stopwatch.
var delay = 16;
var stopwatch = Stopwatch.StartNew();
long current = 0;
long previous;
var next = stopwatch.ElapsedMilliseconds + delay;
for (int i = 0; i < 100; i++)
{
while (next > stopwatch.ElapsedMilliseconds)
{
// Spin
}
next = stopwatch.ElapsedMilliseconds + delay;
previous = current;
current = stopwatch.ElapsedMilliseconds;
var delta = current - previous;
Console.WriteLine("Delta: " + delta);
}
As mentioned in the comments, this does not provide any strong guarantees, merely a best effort. There are also better ways to do this that does not waste an entire thread doing nothing, for example using multi media timers. But it might be adequate for testing/debugging purposes as long as the load on the CPU is light.
I am fairly new to C# (using it for a crpytographic process).
Some help would be greatly appreciated!
I have made a timer that should print out my hash speed every minute. See code below
using System;
using System.Text;
using System.Security.Cryptography;
namespace HashConsoleApp {
class Program {
static void Main(string[] args) {
long Nonce = 19989878659;
long Noncestart = 19989878659;
int Tick = 0;
DateTime start = DateTime.UtcNow;
while (Tick == 0) {
string noncestr = Nonce.ToString();
string plainData = "1" + noncestr + "Sjoerd0000000000000000000000000000000000000000000000000000000000000000";
string hashedData = ComputeSha256Hash(plainData);
// if 10-zeroes hash is found, save to disk
if (hashedData.Substring(0, 10) == "0000000000") {
Tick = Tick + 1;
string writestring = "Nonce: " + noncestr + "\n" + "hashed data: " + hashedData;
System.IO.File.WriteAllText("hash_10.txt", writestring);
}
// print hash speed per second, each minute
DateTime end = DateTime.UtcNow;
TimeSpan span1 = end.Subtract(start);
TimeSpan span2 = end.Subtract(start);
if (span1.Minutes >= 1) {
long diff = (int)(Nonce - Noncestart) / 60;
string diffs = diff.ToString();
Console.Write("Hash speed: " + diffs + " h/s");
System.IO.File.WriteAllText("test.txt", Nonce.ToString());
Noncestart = Nonce;
span1 = TimeSpan.Zero;
}
// save Nonce every hour, reset clock
if (span2.Minutes >= 60) {
start = DateTime.UtcNow;
System.IO.File.WriteAllText("hourly_nonce.txt", Nonce.ToString());
span2 = TimeSpan.Zero;
}
//Console.WriteLine("Raw data: {0}", plainData);
//Console.WriteLine("Hash {0}", hashedData);
//Console.WriteLine(ComputeSha256Hash("1"+noncestr+"Sjoerd0000000000000000000000000000000000000000000000000000000000000000"));
}
}
static string ComputeSha256Hash(string rawData) {
// Create a SHA256
using(SHA256 sha256Hash = SHA256.Create()) {
// ComputeHash - returns byte array
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
// Convert byte array to a string
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++) {
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
}
}
However, after the 1 minute mark this repeadetly keeps on printing on my screen. it looks like it gets stuck in the if statement. Is there something wrong with my code?
This should do the trick for your minute-timer (resetting minuteStart instead of span1):
static void Main(string[] args) {
long Nonce = 19989878659;
long Noncestart = 19989878659;
int Tick = 0;
DateTime start = DateTime.UtcNow;
DateTime minuteStart = DateTime.UtcNow; // ##### (added)
while (Tick == 0) {
// [Process stuff]
// print hash speed per second, each minute
DateTime end = DateTime.UtcNow;
TimeSpan span1 = end.Subtract(minuteStart); // ##### (modified)
if (span1.TotalMinutes >= 1) { // ##### (modified but Minutes should work fine here)
long diff = (int)(Nonce - Noncestart) / 60;
string diffs = diff.ToString();
Console.Write("Hash speed: " + diffs + " h/s");
System.IO.File.WriteAllText("test.txt", Nonce.ToString());
Noncestart = Nonce;
minuteStart = DateTime.UtcNow; // ##### (added)
//span1 = TimeSpan.Zero; // ##### (deleted)
}
// [...]
}
}
(See the lines with // #### comments)
The trick is that resetting span1 is useless because of this line:
TimeSpan span1 = end.Subtract(start);
However, if (span2.Minutes >= 60) will never be entered, as TimeSpan.Minutes "ranges from -59 through 59".
You probably are looking for TotalMinutes here.
Your if (span1.Minutes >= 1) { statement won't mean the printout only occurs once per minute, it will simply cause it to print whenever at least one minute has passed since the program started.
You need to check whether 1 minute has passed since the last printout . Therefore you need to reset the start time every time you run a printout. (N.B. Setting span1 = TimeSpan.Zero as you do now has no effect because you just overwrite that as soon as the loop runs again).
Also your minute and hour tests will conflict with each other once you do this, so you need separate date counters.
So add
DateTime start2 = DateTime.UtcNow;
just below the line where you declare start already.
Then please replace span1 = TimeSpan.Zero; with
start2 = DateTime.UtcNow;
and change TimeSpan span1 = end.Subtract(start);
to
TimeSpan span1 = end.Subtract(start2);
Lastly, replace if (span2.Minutes >= 60) { with
if (span2.TotalMinutes >= 60) {
otherwise this part won't work either because Minutes only reports the minutes in the current hour. You can also remove span2 = TimeSpan.Zero;, this is redundant like the similar line in the first if block.
I've got list of DateTime objects that I need to check if they are a coherent time period.
How is this done?
There might be time gaps that I need to detect and act upon.
Edit:
From what I can see the DateTime objects are sorted.
I've got a TrackerObj class and Entry class the relevant however is only the timestamp in DateTime that each tracker holds:
public class TrackerObj
{
private DateTime timeStamp;
private string trackerId;
private int voltage;
public TrackerObj(string trackerId, DateTime timeStamp, int voltage)
{
this.trackerId = trackerId;
this.timeStamp = timeStamp;
this.voltage = voltage;
}
}
The only relevant here is the timeStamp that from data I've seen are sorted.
Edit: The list is a List each object on that list contains a DateTime timeStamp. In order to determine if the periods between the DateTime are "coherent".
My definition of coherent time:
A period of time where each timestamp are after the other, without gaps (breaks in time).
DateTime format:
mm-dd-yyyy hours:minutes:seconds
private bool arePeriodsCoherent(List<TrackerObj> list)
{
// determine if all the objects on this list are without gaps. Return true if this is true. else return false.
for(int i=0; i < list.Count; i++)
{
if(list[i].timeStamp > list[i + 1].timeStamp || list[i].timeStamp == list[i + 1].timeStamp)
{return false;}
else
{return true;}
}
}
What variations does posible timeStamps contain? Will I the above code fail to catch all scenarios?
This will find any endpoints in a coherent timeperiod:
private List<int> getTimeGapIndexEndPoints(double maxTimeGapSeconds)
{
int x = 1;
List<int> timeLapsIndexes = new List<int>();
for (int i = 0; i < trackerData[trackerId].currentList.Count(); i++)
{
if (x < trackerData[trackerId].currentList.Count())
{
DateTime t1 = trackerData[trackerId].currentList[i].TimeStamp;
DateTime t2 = trackerData[trackerId].currentList[x++].TimeStamp;
TimeSpan duration = t2.Subtract(t1);
if (duration.TotalSeconds > maxTimeGapSeconds)
{
// MessageBoxResult resultb = System.Windows.MessageBox.Show(this, "After index: "+i+" "+duration+" Duration for trackerId: " + trackerId + " exceed " + maxTimeGapSeconds);
timeLapsIndexes.Add(i);
}
}
}
return timeLapsIndexes;
//for (int j = 0; j < timeLapsIndexes.Count(); j++)
//{
// MessageBoxResult resultNumbers = System.Windows.MessageBox.Show(this, "After Index (i+1): " + timeLapsIndexes[j] + " for trackerId: " + trackerId);
//}
}
Have a great day everyone. :)
I've been working for the last few days on a method to compress 144 million tile representation for my xna game down to a very small size when saved. Having managed to pull that off I now find myself stumped on how to go about getting them back from the file in chunks.
In the file I have.
An integer (it gets compressed to bytes using the 7BitEncodedInt method)
A byte
The compressed integer represents the number of tiles and the byte that follows determines what type the tiles are. This is all well and good and works really well. Most importantly it shrinks the file size down to just 50mb on average.
The problem is that I am currently reading back the entire file.
From the file I'm getting this.
The index value of each tile (just a basic iteration as I grab the tiles)
The type for each tile as a byte value
A byte value representing a texture for that tile (this is hard to explain but its necessary on a per tile basis)
The end result of all this is that I'm managing to save the file and only use about 50mb. But by loading the whole thing back in it expands out to nearly 1.5gigs on the ram. I can't really afford to sacrifice anymore tile info. so I need a way to only load portions of the map based on the player location. The goal is to be around the 100-200mb range
I have been looking at memory mapping the file, using quadtrees, pretty much anything I could find for loading files in chunks. While these options all seem pretty good I'm not sure which is best or if given the situation there may be another even better one. The other problem with all this is that these solutions all seem very involved (especially since this is my first time using them) and while I'm not against devoting myself to some lengthy coding I'd like to know that its gonna do what I need it to before hand.
My question is, given how I have to process the file as I pull it in and the fact that it needs to be done based on the players location what would be the best way to do this ? I'm just looking for some direction here. Code is always welcome but not required.
You want to have fixed length variables in your Tile class and implement something like such:
This is an example of a collection class (People) that can get a value based on index from a collection that was serialised into a file.
Person is the class that is the base of the People collection.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FileStreamDatabaseTest
{
class Program
{
static void Main(string[] args)
{
People.OpenCollection();
People.Test_WillOverwriteData();
People.CloseCollection();
Console.ReadLine();
}
}
public class Person
{
// define maxium variable sizes for serialisation
protected static int pMaxLength_FirstName = 64;
protected static int pMaxLength_Age = 10;
public static int MaxObjectSize
{
get
{
// return the sum of all the maxlegnth variables to define the entire object size for serialisation
return pMaxLength_FirstName + pMaxLength_Age;
}
}
// define each object that will be serialised as follows
protected string pFirstName;
public string Firstname
{
set
{
// ensure the new value is not over max variable size
if (value.Length > pMaxLength_FirstName)
throw new Exception("the length of the value is to long.");
pFirstName = value;
}
get
{
return pFirstName;
}
}
protected int pAge;
public int Age
{
get
{
return pAge;
}
set
{
pAge = value;
}
}
public byte[] Serialise()
{
// Output string builder
StringBuilder Output = new StringBuilder();
// Append firstname value
Output.Append(Firstname);
// Add extra spaces to end of string until max length is reached
if (Firstname.Length < pMaxLength_FirstName)
for (int i = Firstname.Length; i < pMaxLength_FirstName; i++)
Output.Append(" ");
// Append age value as string
Output.Append(Age.ToString());
// Add extra spaces to end of string until max length is reached
int AgeLength = Age.ToString().Length;
if (AgeLength < pMaxLength_Age)
for (int i = AgeLength; i < pMaxLength_Age; i++)
Output.Append(" ");
// Return the output string as bytes using ascii encoding
return System.Text.Encoding.ASCII.GetBytes(Output.ToString());
}
public void Deserialise(byte[] SerialisedData)
{
string Values = System.Text.Encoding.ASCII.GetString(SerialisedData);
pFirstName = Values.Substring(0, pMaxLength_FirstName).Trim();
pAge = int.Parse(Values.Substring(pMaxLength_FirstName, pMaxLength_Age).Trim());
}
}
public static class People
{
private static string tileDatasource = #"c:\test.dat";
private static System.IO.FileStream FileStream;
public static void OpenCollection()
{
FileStream = new System.IO.FileStream(tileDatasource, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
}
public static void CloseCollection()
{
FileStream.Close();
FileStream.Dispose();
FileStream = null;
}
public static void SaveCollection(Person[] People)
{
FileStream.SetLength(People.Length * Person.MaxObjectSize);
FileStream.Position = 0;
foreach (Person PersonToWrite in People)
{
// call serialise to get bytes
byte[] OutputBytes = PersonToWrite.Serialise();
// write the output buffer
// note: this will always be the same size as each variable should
// append spaces until its max size is reached
FileStream.Write(OutputBytes, 0, OutputBytes.Length);
}
}
public static Person GetValue(int Index)
{
// set the stream position to read the object by multiplying the requested index with the max object size
FileStream.Position = Index * Person.MaxObjectSize;
// read the data
byte[] InputBytes = new byte[Person.MaxObjectSize];
FileStream.Read(InputBytes, 0, Person.MaxObjectSize);
// deserialise
Person PersonToReturn = new Person();
PersonToReturn.Deserialise(InputBytes);
// retun the person
return PersonToReturn;
}
public static void Test_WillOverwriteData()
{
long StartTime;
long EndTime;
TimeSpan TimeTaken;
Console.WriteLine("-------------------------------------------------------------------");
Console.WriteLine("*** Creating 2,000,000 test people... ");
StartTime = DateTime.Now.Ticks;
Person[] People = new Person[2000000];
for (int i = 0; i < 2000000; i++)
{
People[i] = new Person();
People[i].Firstname = "TestName." + i;
People[i].Age = i;
}
EndTime = DateTime.Now.Ticks;
TimeTaken = new TimeSpan(EndTime - StartTime);
Console.WriteLine("-> Completed in " + TimeTaken.TotalSeconds + " seconds");
Console.WriteLine("-------------------------------------------------------------------");
Console.WriteLine("*** Serialising Collection to disk... ");
StartTime = DateTime.Now.Ticks;
SaveCollection(People);
EndTime = DateTime.Now.Ticks;
TimeTaken = new TimeSpan(EndTime - StartTime);
Console.WriteLine("-> Completed in " + TimeTaken.TotalSeconds + " seconds");
Console.WriteLine("-------------------------------------------------------------------");
Console.WriteLine("*** Redundancy Test... ");
StartTime = DateTime.Now.Ticks;
bool Parsed = true;
int FailedCount = 0;
for (int i = 0; i < 2000000; i++)
{
if (GetValue(i).Age != i)
{
Parsed = false;
FailedCount++;
}
}
EndTime = DateTime.Now.Ticks;
TimeTaken = new TimeSpan(EndTime - StartTime);
Console.WriteLine("-> " + (Parsed ? "PARSED" : "FAILED (" + FailedCount + " failed index's"));
Console.WriteLine("-> Completed in " + TimeTaken.TotalSeconds + " seconds");
Console.WriteLine("-------------------------------------------------------------------");
Console.WriteLine("*** Reading 10,000 index's at once... ");
StartTime = DateTime.Now.Ticks;
Person[] ChunkOfPeople = new Person[10000];
for (int i = 0; i < 10000; i++)
ChunkOfPeople[i] = GetValue(i);
EndTime = DateTime.Now.Ticks;
TimeTaken = new TimeSpan(EndTime - StartTime);
Console.WriteLine("-> Completed in " + TimeTaken.TotalSeconds + " seconds");
Console.WriteLine("-------------------------------------------------------------------");
Console.WriteLine("*** Reading 100,000 index's at once... ");
StartTime = DateTime.Now.Ticks;
ChunkOfPeople = new Person[100000];
for (int i = 0; i < 100000; i++)
ChunkOfPeople[i] = GetValue(i);
EndTime = DateTime.Now.Ticks;
TimeTaken = new TimeSpan(EndTime - StartTime);
Console.WriteLine("-> Completed in " + TimeTaken.TotalSeconds + " seconds");
Console.WriteLine("-------------------------------------------------------------------");
Console.WriteLine("*** Reading 1,000,000 index's at once... ");
StartTime = DateTime.Now.Ticks;
ChunkOfPeople = new Person[1000000];
for (int i = 0; i < 1000000; i++)
ChunkOfPeople[i] = GetValue(i);
EndTime = DateTime.Now.Ticks;
TimeTaken = new TimeSpan(EndTime - StartTime);
Console.WriteLine("-> Completed in " + TimeTaken.TotalSeconds + " seconds");
}
}
}
There are a number of options, not all of them may be appropriate for your particular project:
Don't use a single file for all the data. Divide the map in smaller "rooms" and store each one in its own file. Load only the "room" the player starts in and preemptively load neighboring "rooms" and unload old ones.
Reduce the number of tiles you need to store. Use procedural generation to create an area's layout.
If you have a 10x10 room with the floor made of a single tile type then don't store 100 separate tiles but instead use a specific marker that says "this area has a 10x10 floor with this tile". If it's a wall then save the start and end positions and the texture type. If you have a multi-tile doodad in the middle of an open field and it's position is not relevant to the story then position it randomly in the field (and save the seed for the random number generator in the map file so next time it will appear in the same place).
Is there any significant advantages for converting a string to an integer value between int.Parse() and Convert.ToInt32() ?
string stringInt = "01234";
int iParse = int.Parse(stringInt);
int iConvert = Convert.ToInt32(stringInt);
I found a question asking about casting vs Convert but I think this is different, right?
When passed a string as a parameter, Convert.ToInt32 calls int.Parse internally. So the only difference is an additional null check.
Here's the code from .NET Reflector
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
For what its worth:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int iterations = 1000000;
string val = "01234";
Console.Write("Run 1: int.Parse() ");
DateTime start = DateTime.Now;
DoParse(iterations, val);
TimeSpan duration = DateTime.Now - start;
Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");
Console.Write("Run 1: Convert.ToInt32() ");
start = DateTime.Now;
DoConvert(iterations, val);
duration = DateTime.Now - start;
Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");
Console.Write("Run 2: int.Parse() ");
start = DateTime.Now;
DoParse(iterations, val);
duration = DateTime.Now - start;
Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");
Console.Write("Run 2: Convert.ToInt32() ");
start = DateTime.Now;
DoConvert(iterations, val);
duration = DateTime.Now - start;
Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");
Console.Write("Run 3: int.Parse() ");
start = DateTime.Now;
DoParse(iterations, val);
duration = DateTime.Now - start;
Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");
Console.Write("Run 3: Convert.ToInt32() ");
start = DateTime.Now;
DoConvert(iterations, val);
duration = DateTime.Now - start;
Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString() + "ms");
Console.ReadKey();
}
static void DoParse(int iterations, string val)
{
int x;
for (int i = 0; i < iterations; i++)
{
x = int.Parse(val);
}
}
static void DoConvert(int iterations, string val)
{
int x;
for (int i = 0; i < iterations; i++)
{
x = Convert.ToInt32(val);
}
}
}
}
Result of 1,000,000 iterations of each:
Run 1: int.Parse() Duration: 312.5ms
Run 1: Convert.ToInt32() Duration: 328.125ms
Run 2: int.Parse() Duration: 296.875ms
Run 2: Convert.ToInt32() Duration: 312.5ms
Run 3: int.Parse() Duration: 312.5ms
Run 3: Convert.ToInt32() Duration: 312.5ms
The difference lies in the way both handles NULL value.
When encountered a NULL Value, Convert.ToInt32 returns a value 0.
On other hand,Parse is more sensitive and expects a valid value.
So it would throw an exception when you pass in a NULL.
See this discussion for details.
Convert.ToInt32 won't throw as often (if stringInt == null, it returns 0 instead of throwing an exception), but has a slight bit more overhead since it's doing a few extra checks, then calling int.Parse internally.
I wrote the code below and the result was that int.parse is slower than convert.toint32.
static void Main(string[] args) {
Console.WriteLine(TimeConvertTo());
Console.WriteLine(TimeParse());
}
static TimeSpan TimeConvertTo() {
TimeSpan start = DateTime.Now.TimeOfDay;
for (int i = 0; i < 99999999; i++) {
Convert.ToInt32("01234");
}
return DateTime.Now.TimeOfDay.Subtract(start);
}
static TimeSpan TimeParse() {
TimeSpan start = DateTime.Now.TimeOfDay;
for (int i = 0; i < 99999999; i++) {
int.Parse("01234");
}
return DateTime.Now.TimeOfDay.Subtract(start);
}
There are some performance implications as others have mentioned. If you look at the test code and performance stats from this website:
Int.Parse() and Int.TryParse() generally perform faster as the number of conversions you're performing increases.
Convert.ToInt() seems to perform best with a low number of conversions
The overall fastest way to convert a string to an int (assuming no exceptions) regardless of the number of conversions you need to perform is:
_
y = 0; //the resulting number from the conversion
//loop through every char in the string, summing up the values for the final number
for (int i = 0; i < s[x].Length; i++)
y = y * 10 + (s[x][i] - '0');
Both of the them are slow. If you know the exact format of input string and care about speed, I suggest you write the convert function by yourself.