У меня есть значения, хранящиеся в виде строк в DataTable
, где каждое значение действительно может представлять int
, double
или string
(все они были преобразованы в строки во время процесса импорта из внешнего источника данных). Мне нужно проверить и посмотреть, к какому типу на самом деле относится каждое значение.
Что для приложения эффективнее (или нет практической разницы)?
int
(а потом в double
). Если конвертация работает, верните true
. Если возникло исключение, верните false
.int
или double
Будет использовать double.TryParse, у него есть преимущества в производительности.
Я бы лично использовал int.tryparse, затем double.tryparse. Эти методы работают довольно быстро. Оба они возвращают логическое значение. Если оба не работают, то у вас есть строка в соответствии с тем, как вы определили свои данные.
Я бы сказал, не беспокойтесь о такой микропроизводительности. Гораздо лучше просто заставить что-то работать, а затем сделать это как можно более ясным, кратким и легким для чтения. Худшее, что вы можете сделать, - это пожертвовать удобочитаемостью ради незначительной производительности.
В конце концов, лучший способ справиться с проблемами производительности - сохранить их на тот случай, когда у вас есть данные, указывающие на наличие реальной проблемы с производительностью ... в противном случае вы потратите много времени на микрооптимизацию и фактически вызовете более высокие затраты на обслуживание для позже.
Если вы обнаружите, что эта ситуация синтаксического анализа действительно является узким местом в вашем приложении, ТОГДА самое время попытаться выяснить, каков самый быстрый способ решения проблемы. Я думаю, что Джефф (и многие другие) много писали об этом в блогах.
Вы получите разные результаты для разных методов в зависимости от того, выполняете ли вы компиляцию с оптимизацией. В основном у вас есть несколько вариантов:
object o;
//checking with is
o is int
//check type
o.GetType() != typeof( int )
//cast and catch exception
try{ int j = (int) o; }
catch {}
//use the tryparse
int.TryParse( Convert.ToString( o ), out j )
Вы можете легко настроить консольное приложение, которое пробует каждый из этих 10000 раз и возвращает продолжительность для каждого (проверьте, когда o - это int, а когда это что-то еще).
Метод try-catch
является самым быстрым, если объект содержит int, и намного медленнее, если его нет (даже медленнее, чем GetType
). int.TryParse
работает довольно быстро, если у вас есть строка, но если у вас есть неизвестный объект, он работает медленнее.
Интересно, что с .Net 3.5 и включенной оптимизацией проверка o is int
занимает то же время, что и try-catch
, когда o на самом деле является int. o is int
только немного медленнее, если o на самом деле что-то другое.
Раздражающе FxCop выдаст предупреждения, если вы сделаете что-то вроде:
if ( o is int )
int j = (int) o;
Но я думаю, что это ошибка в FxCop - он не знает, что int является типом значения, и рекомендует вместо этого использовать o as int
.
Если ваш ввод всегда является строкой, лучше всего подходит int.TryParse
, в противном случае оператор is
работает быстрее всего.
Поскольку у вас есть строка, я бы посмотрел, нужно ли вам знать, что это int, а не double. Если int.TryParse
проходит, то также и double.TryParse
, поэтому вы можете вдвое сократить количество проверок - вернуть либо double, либо строку и заполнить двойные значения, когда вы ожидаете int.
Проблема в том, что могут быть ситуации, в которых могут быть ответы всех трех типов.
3 может быть целым, двойным или строковым!
Это зависит от того, что вы пытаетесь сделать, и насколько важно, чтобы они принадлежали к определенному типу. Возможно, лучше всего оставить их такими, какие они есть, как можно дольше, или, в качестве альтернативы, добавить способ пометить каждую из них (если у вас есть контроль над источником исходной строки).
Конечная цель состояла в том, чтобы попытаться определить наиболее эксклюзивный тип данных для объекта. 3 будет int. 3,5 будет дубль. «Тройка» будет строкой. В конце концов я собрал функцию, которая пробовала несколько вызовов object.TryParse до тех пор, пока не могла определить, какой тип данных является «наиболее подходящим».