Napisałem dwie funkcje, które konwertują ciąg liczb całkowitych rozdzielonych białymi znakami na tablicę int. Pierwsza funkcja wykorzystuje Substring
a następnie stosuje System.Int32.Parse
przekonwertować podciąg do wartości int
:Szybsze parsowanie liczb na .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()
Druga funkcja przemierza znaków napisu w miejscu akumulowanie całkowitą bez tworzenia tymczasowego podciąg:
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()
Analiza porównawcza na liczbach całkowitych oddzielających spacją od 1 do 1 000 000, pierwsza wersja zajmuje 1,5 s, natomiast druga wersja to 0,3 s.
Parsowanie takich wartości może być krytyczne dla wydajności, więc pozostawienie 5x wydajności tabeli za pomocą tymczasowych podciągów może być niepożądane. Analizowanie liczb całkowitych jest łatwe, ale przetwarzanie innych wartości, takich jak liczby zmiennoprzecinkowe, dziesiętne i daty jest znacznie trudniejsze.
Czy istnieją wbudowane funkcje do analizowania bezpośrednio z podłańcucha w ciągu znaków (to znaczy przy użyciu podanego początku i długości ciągu znaków), aby uniknąć generowania tymczasowego ciągu znaków? Jeśli nie, czy są jakieś biblioteki, które zapewniają wydajne funkcje, aby to zrobić?
Czy próbowałeś używać wyrażeń regularnych zamiast używać Substring? Skompilowane wyrażenie regularne może być znacznie szybsze niż operacje na ciągach znaków –
@PanagiotisKanavos Czy możesz wyjaśnić, w jaki sposób można użyć wyrażenia regularnego do parsowania ciągu znaków w tablicy ints? –
Niedawno miałem podobny problem i nie mogłem go znaleźć podczas wyszukiwania, musiałem samemu napisać dziesiętny kod parsujący. Nie jest to tak trudne, jak mogłoby się wydawać, ponieważ klasa dziesiętna ma konstruktor, który przyjmuje współczynnik skali, więc możesz zrobić to samo, co analizowanie liczb całkowitych i śledzić, gdzie znajduje się przecinek dziesiętny. Daty też nie były zbyt trudne, jednak w obu przypadkach miałem ścisłą kontrolę nad formatami. Nie chciałbym pisać ogólnego kodu parsującego ... – MrKWatkins