Я написал две функции, которые преобразуют строку целых чисел, разделенных пробелами, в массив int. Первая функция использует Substring
, а затем применяет System.Int32.Parse
для преобразования подстроки в значение int
:
let intsOfString (s: string) =
let ints = ResizeArray()
let rec inside i j =
if j = s.Length then
ints.Add(s.Substring(i, j-i) |> System.Int32.Parse)
else
let c = s.[j]
if '0' <= c && c <= '9' then
inside i (j+1)
else
ints.Add(s.Substring(i, j-i) |> System.Int32.Parse)
outside (j+1)
and outside i =
if i < s.Length then
let c = s.[i]
if '0' <= c && c <= '9' then
inside i (i+1)
else
outside (i+1)
outside 0
ints.ToArray()
Вторая функция пересекает символы строки на месте, аккумулируя целое число без создания временной подстроки:
let intsOfString (s: string) =
let ints = ResizeArray()
let rec inside n i =
if i = s.Length then
ints.Add n
else
let c = s.[i]
if '0' <= c && c <= '9' then
inside (10*n + int c - 48) (i+1)
else
ints.Add n
outside(i+1)
and outside i =
if i < s.Length then
let c = s.[i]
if '0' <= c && c <= '9' then
inside (int c - 48) (i+1)
else
outside (i+1)
outside 0
ints.ToArray()
Бенчмаркинг по целым числам от 1 до 1 000 000, первая версия занимает 1,5 секунды, тогда как вторая версия занимает 0,3 с.
Анализ таких значений может быть критичным по производительности, поэтому сохранение 5-кратной производительности в таблице с использованием временных подстрок может быть нежелательным. Разделение целых чисел легко, но синтаксический анализ других значений, таких как числа с плавающей запятой, десятичные знаки и даты, значительно сложнее.
Итак, существуют ли встроенные функции для синтаксического анализа непосредственно из подстроки внутри строки (т.е. с использованием заданного начала и длины строки), чтобы избежать генерации временной строки? Если нет, существуют ли библиотеки, которые предоставляют эффективные функции для этого?