If I have a string, such as 1 2 3 , and I determine the position of the substring containing double , how can I parse it directly from the substring without creating a temporary string?
For example, I could do System.Double.Parse(str.Substring(0, 1)) , but that would create a temporary string that would be slow and unnecessary. Is it possible to parse a double element directly from part of the source string?
EDIT
Eric Lippert questioned my motives here, stating that "Small strings are cheap." The motivation for this comes from the fact that I am doing the same for parsing ints and I see a significant performance improvement, because apparently small lines are not so cheap.
Here is a function that leaks the sequence of ints through temporary lines:
let lex f (s: string) = let rec inside i0 (s: string, i) = if i = s.Length then f (s.Substring(i0, i-i0) |> System.Int32.Parse) else let c = s.[i] if '0'<=c && c<='9' then inside i0 (s, i+1) else f (s.Substring(i0, i-i0) |> System.Int32.Parse) outside (s, i) and outside (s: string, i) = if i < s.Length then let c = s.[i] if '0'<=c && c<='9' then inside i (s, i) else outside (s, i+1) outside (s, 0)
It takes from 2.4s to lex 15,625,000 ints per line.
Here is a version that avoids temporary lines:
let lex f (s: string) = let rec inside n (s: string, i) = if i = s.Length then fn else let c = s.[i] if '0'<=c && c<='9' then inside (10*n + int c - int '0') (s, i+1) else fn outside (s, i) and outside (s: string, i) = if i < s.Length then let c = s.[i] if '0'<=c && c<='9' then inside 0 (s, i) else outside (s, i+1) outside (s, 0)
It takes 0.255s, more than 9 times faster than a solution using timelines.
I see no reason why floating vocabulary should be different. Therefore, without providing the ability to parse float from a .NET substring, it remains an order of magnitude higher in performance on the table. I do a lot of scientific computing and often have a lot of data for lex, especially at startup, so I really don't want to throw performance down the drain like this.