Подтвердить что ты не робот

Что самое быстрое: (int), Convert.ToInt32 (x) или Int32.Parse(x)?

Какой из следующих кодов является наиболее быстрой/лучшей практикой для преобразования некоторого объекта x?

int myInt = (int)x;

или

int myInt = Convert.ToInt32(x);

или

int myInt = Int32.Parse(x);

или в случае строки '

int myInt;
Int32.TryParse(s, out myInt);

Мне любопытно, для чего выполняется самый быстрый для типов данных, которые имеют метод в Convert, а не только для ints. Я просто использовал int в качестве примера.

Изменить: этот случай возник из-за получения информации из данных. Will (int) все еще работает быстрее всего?

Из некоторого тестирования, когда объект x = 123123123, int выполняет самый быстрый, как многие говорили. Когда x является строкой, Parse работает быстрее (примечание: cast бросает исключение). Мне действительно интересно, как они запускаются, когда значение извлекается следующим образом:

foreach(DataRow row in someTable.Rows)
{
    myInt = (int)row["some int value"];
    myInt2 = Int.Parse(row["some int value"]);
    myInt2 = Convert.ToInt32(row["some int value"]);
}
4b9b3361

Ответ 1

Почему бы вам просто не попробовать несколько тысяч раз?

(это касается всех вопросов "Что является самым быстрым:" )


Хммм, много понижений за эти годы... Думаю, я должен расширить этот ответ.

Вышеизложенное утверждение было сделано с некоторой легкостью в молодости, однако я до сих пор согласен с его чувствами. Не стоит тратить время на создание вопроса SO, спрашивающего других, что, по их мнению, быстрее из двух или трех операций, которые занимают менее 1 мс каждый.

Тот факт, что один может пройти цикл или два дольше, чем другой, почти наверняка будет незначительным в повседневном использовании. И если вы заметили проблему производительности в своем приложении, когда вы конвертируете миллионы объектов в ints, , где вы можете профилировать фактический код, и вы легко сможете проверить, int-преобразование на самом деле является узким местом.

И если сегодня это конвертер object-int, завтра, может быть, вы подумаете, что ваш конвертер объекта-DateTime занимает много времени. Вы бы создали еще один вопрос SO, чтобы узнать, какой самый быстрый метод?

Что касается вашей ситуации (без сомнения, давно уже разрешенной), как упоминалось в комментарии, вы запрашиваете базу данных, поэтому преобразование объектов-int является наименьшим из ваших забот. Если бы я был вами, я бы использовал любой из методов конверсии, о которых вы говорили. Если возникает проблема, я бы изолировал вызов, используя профилировщик или протоколирование. Затем, когда я замечаю, что преобразование объекта-объекта выполняется миллион раз, и общее время, затраченное на это преобразование, выглядит относительно высоким, я бы изменил использование другого метода преобразования и повторного профиля. Выберите метод преобразования, который занимает наименьшее время. Вы даже можете протестировать это в отдельном решении, или даже LINQPad, или Powershell и т.д.

Ответ 2

Это зависит от того, что вы ожидаете от x

Если x является вложенным int, тогда (int)x является самым быстрым.

Если x является строкой, но определенно является допустимым числом, тогда int.Parse(x) лучше

Если x - строка, но она может быть недействительной, то int.TryParse(x) намного быстрее, чем блок try-catch.

Разница между Parse и TryParse незначительна во всех, кроме самых больших циклах.

Если вы не знаете, что такое x (возможно, строка или коробочный int), тогда лучше Convert.ToInt32(x).

Эти обобщенные правила также верны для всех типов значений со статическими методами Parse и TryParse.

Ответ 3

Самый быстрый!= Лучшая практика!

Например, (int) почти наверняка самый быстрый, поскольку он скорее оператор, чем вызов функции, но он будет работать только в определенных ситуациях.

Лучшая практика - использовать наиболее читаемый код, который не будет отрицательно влиять на вашу производительность, и 99 раз из 100 целочисленное преобразование не влияет на производительность вашего приложения. Если это так, используйте наиболее подходящее, самое узкое преобразование. Иногда это (int). Иногда это TryParse(). Иногда это Convert.ToInt32().

Ответ 4

Если вы знаете, что данные определенно являются int, тогда int myInt = (int)x; должен быть самым быстрым. В противном случае TryParse поможет вам сделать это правильно без медлительности исключений.

BTW:

(int), однако, освобождает только файлы,

(int) IL =

  .locals init (
        [0] object x,
        [1] int32 Y)
    L_0000: ldc.i4.1 
    L_0001: box int32
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: unbox int32
    L_000d: ldobj int32
    L_0012: stloc.1 
    L_0013: ret 

Convert.ToInt32 =

.locals init (
        [0] object x,
        [1] int32 Y)
    L_0000: ldc.i4.1 
    L_0001: box int32
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
    L_000d: call int32 [mscorlib]System.Convert::ToInt32(object)
    L_0012: stloc.1 
    L_0013: ret 

Ответ 5

Когда у меня возникают вопросы о различиях в производительности между различными способами делать что-то конкретное, как это, я обычно делаю новую запись в своей копии MeasureIt, бесплатную загрузку с большой статья MSDN от Vance Morrison. Для получения дополнительной информации обратитесь к статье.

Добавив простой код кода в MeasureIt, я получаю результаты, ниже которых сравниваются фактические тайминги различных методов преобразования в int. Обратите внимание, что приведение из строки в int вызовет исключение и недействительно, поэтому я просто добавил перестановки, которые имели смысл для меня.

Name                                                Median   Mean     StdDev   Min      Max    Samples       
IntCasts: Copy [count=1000 scale=10.0]              0.054    0.060    0.014    0.054    0.101    10       
IntCasts: Cast Int [count=1000 scale=10.0]          0.059    0.060    0.007    0.054    0.080    10       
IntCasts: Cast Object [count=1000 scale=10.0]       0.097    0.100    0.008    0.097    0.122    10       
IntCasts: int.Parse [count=1000 scale=10.0]         2.721    3.169    0.850    2.687    5.473    10       
IntCasts: Convert.ToInt32 [count=1000 scale=10.0]   3.221    3.258    0.067    3.219    3.418    10     


Чтобы найти лучшую производительность для различных типов, которые вас интересуют, просто расширьте приведенный ниже код, что буквально все, что мне нужно было добавить в MeasureIt, чтобы создать приведенную выше таблицу.

static unsafe public void MeasureIntCasts()
{
    int result;
    int intInput = 1234;
    object objInput = 1234;
    string strInput = "1234";

    timer1000.Measure("Copy", 10, delegate
    {
        result = intInput;
    });
    timer1000.Measure("Cast Object", 10, delegate
    {
        result = (int)objInput;
    });

    timer1000.Measure("int.Parse", 10, delegate
    {
        result = int.Parse(strInput);
    });

    timer1000.Measure("Convert.ToInt32", 10, delegate
    {
        result = Convert.ToInt32(strInput);
    });
}

Ответ 6

Лучшей практикой будет TryParse, и, увидев результат этого, если он сработает - иначе вы могли бы получить исключения

Ответ 7

При оптимизации сетки привязанных данных в .Net 2, я обнаружил, что почти половина времени проводилась в различных методах Object ToString(), которые затем использовались в качестве входов операций преобразования. Выделив эти случаи и, если это возможно, выбрал правильный тип (поскольку они были выведены из базы данных, и на них можно было ссылаться), это привело к значительному увеличению скорости этой операции привязки данных.

Итак, если вы знаете тип вещи впереди, и вы достаточно быстро нажмете кусок кода, стоит приложить его прямо, вместо того, чтобы конвертировать, когда это необходимо.

Ответ 8

Расширение теста Эрика Коски на альтернативы от Сэма Аллена, я обнаружил, что если вы знаете, что ваша строка действительное целое число, а затем его синтаксический анализ выполняется намного быстрее.

Я продлил тест в следующих случаях:

    timer1000.Measure("IntParseFast", 10, delegate
    {
        result = Misc.IntParseFast(strInput);
    });

    timer1000.Measure("IntParseUnsafe", 10, delegate
    {
        result = Misc.IntParseUnsafe(strInput);
    });

Со следующими реализациями:

public static int IntParseFast(string value)
{
    int result = 0;
    int length = value.Length;
    for (int i = 0; i < length; i++)
    {
        result = 10 * result + (value[i] - 48);
    }
    return result;
}

public unsafe static int IntParseUnsafe(string value)
{
    int result = 0;
    fixed (char* v = value)
    {
        char* str = v;
        while (*str != '\0')
        {
            result = 10 * result + (*str - 48);
            str++;
        }
    }
    return result;
}

Получаю следующие результаты:

IntCaint.Parse                5,495
IntCaConvert.ToInt32          5,653
IntCaIntParseFast             1,154
IntCaIntParseUnsafe           1,245

Ответ 9

Не уверен в производительности, но эти методы не совпадают. И Parse, и TryParse работают со строкой, анализируется представление объекта String (см. MSDN).

Преобразует строковое представление числа в его 32-разрядный эквивалент со знаком.

Не уверен в том, что кастинг и класс Convert, но приведение только для объектов, которые уже являются целыми, но не сильно типизированы.

Маттиас

Ответ 10

Если вам нужна дополнительная скорость, было бы легко проверить различные варианты. Поскольку вы их не тестируете, они вам не нужны. Не тратьте время на бессмысленные микрооптимизации!

Ответ 11

(int) преобразование в строку не будет работать, поэтому я не проверю его. Convert.ToInt32 отражает как проверяющее значение значение null, а THEN вызывает int.Parse, поэтому в общем случае он должен быть медленнее, чем int.Parse().

Ответ 12

foreach(DataRow row in someTable.Rows)
{
    myInt = (int)row["some int value"];
    myInt2 = Int.Parse(row["some int value"]);
    myInt2 = Convert.ToInt32(row["some int value"]);
}

В этом примере, если значение, поступающее из таблицы, действительно является значением int или сопоставимым значением базы данных, то с помощью

myInt = (int)row["some int value"];

будет наиболее эффективным и, следовательно, "самым быстрым" из-за

row["some int value"];

будет экземпляром int типа значения, помещенным внутри экземпляра объекта ссылочного типа, поэтому использование явного типа cast будет самым быстрым, потому что другие люди говорят, что это операция, а не вызов функции, тем самым уменьшая требуемые операции процессора, Вызов метода конвертации или разбора потребует дополнительных операций cpu и, следовательно, не будет "быстрым".

Ответ 13

это неверно. Быстрое преобразование - прямое действие:

int i = (int) stringData;

watch.Elapsed = {00:00:00.1732388}
watch2.Elapsed= {00:00:00.0878196}


 // Mesary start
                Stopwatch watch = new Stopwatch();

                watch.Start();
                for (int f = 1; f < 1000000; f++)
                {
                    item.Count = FastInt32.IntParseFast(dt.Rows[i]["TopCount"]);
                }   // Execute the task to be timed
                watch.Stop();

                Console.WriteLine("Elapsed: {0}", watch.Elapsed);
                Console.WriteLine("In milliseconds: {0}", watch.ElapsedMilliseconds);
                Console.WriteLine("In timer ticks: {0}", watch.ElapsedTicks);
                // Mesary end


                // Mesary start
                Stopwatch watch2 = new Stopwatch();

                watch2.Start();
                for (int n = 1; n < 1000000; n++)
                {
                    item.Count = (int)(dt.Rows[i]["TopCount"]);
                }   // Execute the task to be timed
                watch2.Stop();

                Console.WriteLine("Elapsed: {0}", watch2.Elapsed);
                Console.WriteLine("In milliseconds: {0}", watch2.ElapsedMilliseconds);
                Console.WriteLine("In timer ticks: {0}", watch2.ElapsedTicks);
                // Mesary end

Ответ 14

Кто-то уже выполнил бенчмаркинг. Вот результаты. Самый быстрый способ, если вы знаете, что вы конвертируете, всегда будет действительным int, заключается в использовании следующего метода (который несколько человек ответили выше):

int value = 0;
for (int i = 0; i < str.Length; i++)
{
    value = value * 10 + (str[i] - '0');
}

Другими методами, которые были были следующие:

  • Convert.ToInt32
  • Int32.TryParse
  • int.Parse

Ответ 15

В конце концов, все они вызывают:

System.Number.ParseInt32(string s, NumberStyles style, NumberFormatInfo info);

Итак, в общем, не будет никакой разницы, что так было.

Посмотрите .NET Reflector, чтобы увидеть это.