On Feb 18, 12:27 pm, "Stephen C. Gilardi" <
squee...@mac.com> wrote:
> This is from issue 47, svn 1229. It's unfortunate that a class can't
> be both a BufferedReader and a PushbackReader simultaneously. Those
> classes were implemented using class inheritance rather than via
> interfaces. In this case, the default *in* is not a BufferedReader,
> but does provide readLine. It looks to me like removing the hint is
> the correct fix.
Thanks, Steve -- I wasn't able to track down which revision introduced
the breakage. Now I understand the motivation (avoiding reflection):
user=> (set! *warn-on-reflection* true)
true
user=> (.readLine *in*)
Reflection warning, line: 2 - reference to field readLine can't be
resolved.
hello
"hello"
user=> (.readLine #^clojure.lang.LineNumberingPushbackReader *in*)
hello
"hello"
&, if I follow, the latter isn't robust because we need to allow for
*in* to be dynamically rebound, & wouldn't want to require that it's
always a LineNumberingPR.
Some microbenchmarking (details below) shows that doing an instance?
check combined with type hinting is almost twice as fast as relying on
reflection, & hardly slower than the type-hinted code w/o an instance?
check. How does the following implementation strike you?
(defn r-l []
(if (instance? clojure.lang.LineNumberingPushbackReader *in*)
(.readLine #^clojure.lang.LineNumberingPushbackReader *in*)
(.readLine #^java.io.BufferedReader *in*)))
Best,
Perry
--- 10 runs w/o type hinting: 0.119 msecs (avg) --
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.105 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.116 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.113 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.122 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.153 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.108 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.11 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.115 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.125 msecs"
" \"hello\""
user=> (time (.readLine *in*)) "hello"
"Elapsed time: 0.124 msecs"
" \"hello\""
--- 10 runs with (r-l) func: 0.058 msecs (avg) ---
user=> (time (r-l)) "hello"
"Elapsed time: 0.055 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.055 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.064 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.061 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.057 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.056 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.058 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.062 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.054 msecs"
" \"hello\""
user=> (time (r-l)) "hello"
"Elapsed time: 0.061 msecs"
" \"hello\""