He escrito dos funciones que convierten una cadena de enteros separados por espacios en blanco en una matriz int. La primera función utiliza Substring
y luego se aplica System.Int32.Parse
para convertir la subcadena en un valor int
:Análisis más rápido de números en .NET
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()
La segunda función atraviesa los caracteres de la cadena en el lugar acumular el número entero sin crear una subcadena temporal:
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()
Benchmarking en enteros separados por espacios 1 a 1,000,000, la primera versión toma 1.5s mientras que la segunda versión toma 0.3s.
Analizar tales valores puede ser crítico para el rendimiento, por lo que dejar el rendimiento 5x en la tabla mediante el uso de subcadenas temporales puede ser indeseable. El análisis de números enteros es fácil, pero el análisis de otros valores como números de punto flotante, decimales y fechas es considerablemente más difícil.
Entonces, ¿hay funciones integradas para analizar directamente desde una subcadena dentro de una cadena (es decir, utilizando el inicio y la longitud de una cadena) para evitar generar una cadena temporal? Si no, ¿hay alguna biblioteca que brinde funciones eficientes para hacer esto?
¿Ha intentado utilizar expresiones regulares en lugar de utilizar Substring? Una expresión regular compilada puede ser mucho más rápida que las operaciones de cadena –
@PanagiotisKanavos ¿Puede explicar cómo se puede usar una expresión regular para analizar una cadena en una matriz de entradas? –
Tuve un problema similar recientemente y no pude encontrar ninguno cuando busqué, tuve que escribir el código de análisis decimal yo mismo. No es tan difícil como podrías pensar, ya que la clase Decimal tiene un constructor que toma un factor de escala para que puedas hacer más o menos lo mismo que el análisis de enteros y simplemente hacer un seguimiento de dónde está el punto decimal. Las fechas tampoco fueron muy difíciles, sin embargo tuve un control estricto sobre los formatos en ambos casos. No me gustaría escribir el código de análisis general ... – MrKWatkins