Hmmm... its kinda challenging to find a method for reading/writing data faster enough to get ACCEPTED in this problem ( https://www.spoj.pl/problems/INTEST/ ) using F#.
My code ( http://pas开发者_如何学编程te.ubuntu.com/548748/ ) gets TLE...
Any ideas how to speed up data reading?
This version of mine passes the time limit (but is still terribly slow ~14 seconds):
open System
open System.IO
// need to change standard buffer, not to add an additional one
let stream = new StreamReader(Console.OpenStandardInput(4096))
let stdin = Seq.unfold (fun s -> if s = null then None else Some (s,stream.ReadLine())) <| stream.ReadLine()
let inline s2i (s : string) = Array.fold (fun a d -> a*10u + (uint32 d - uint32 '0') ) 0u <| s.ToCharArray()
let calc =
let fl = Seq.head stdin
let [|_;ks|] = fl.Split(' ')
let k = uint32 ks
Seq.fold (fun a s -> if (s2i s) % k = 0u then a+1 else a) 0 <| Seq.skip 1 stdin
printf "%A" calc
Though the bottle-neck of this version is actually string -> uint32
conversion (standard uint32 cast from string is even slower) the reading itself takes around 2 sec (vs 6 sec of total time) on my sample input (~100M file) - still not a great result. Once s2i
is rewritten in imperative style, the total run-time can be reduced to 10 sec on spoj:
let inline s2i (s : string) =
let mutable a = 0u
for i in 0..s.Length-1 do a <- a*10u + uint32 (s.Chars(i)) - uint32 '0'
a
I don't actually know, but I would guess that reading a since character at a time is bad, and you should read e.g. 4k into a buffer at a time and then process the buffer.
let buf =
let raw = System.Console.OpenStandardInput()
let bytebuf = new System.IO.BufferedStream(raw)
new System.IO.StreamReader(bytebuf)
buf.Read() // retrieves a single character as an int from the buffer
buf.ReadLine() // retrieves a whole line from the buffer
精彩评论