How to profile multithreaded clojure results with Tufte - clojure

Tutfe is a profiling library which is a great fit for understanding the composition of runtime, especially in complicated call stacks.
When I ran it in my project, a section of code I expected to be performance-expensive didn't register as a high-offender in the results, which led to the discovery that Tufte (reasonably) had only captured the thread-local results.
The docs indicate that it has built-in binding to instrument accumulated time on other threads using the {:dynamic? true} option, but there appears to be more needed in order to capture the time accumulated on other threads, such as those initiated by pmap
Here's the original Tufte demo, with some multithreading introduced:
(require '[taoensso.tufte :as tufte :refer (defnp p profiled profile)])
;; We'll request to send `profile` stats to `println`:
(tufte/add-basic-println-handler! {})
;;; Let's define a couple dummy fns to simulate doing some expensive work
(defn get-x [] (Thread/sleep 500) "x val")
(defn get-y []
(pmap
#(do
(Thread/sleep 500)
(print %))
(range 10)))
;; How do these fns perform? Let's check:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(p :get-y (get-y))))
The output indicates that the println statements forced the threads to evaluate. And yet, the get-y accumulated time does not show up in the results:
2187306594=> nil
=> #{:basic-println}
=> #'user/get-x
=> #'user/get-y
8904365271703695842110783956243415760829=> nil
pId nCalls Min Max MAD Mean Time% Time
:get-x 5 500.52ms 504.84ms 1.44ms 502.44ms 100 2.51s
:get-y 5 90.67μs 581.91μs 162.2μs 269.29μs 0 1.35ms
Clock Time 100 2.51s
Accounted Time 100 2.51s

Answer: lazy initialization. Though the data was being printed to the screen, it was the end of the (profile...) form that was doing it, outside of the spied-upon form get-y.
This would yield the same effect:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(doall (p :get-y (get-y)))))
30167894521045768392530798241651268940371023657894=> nil
pId nCalls Min Max MAD Mean Time% Time
:get-x 5 500.07ms 504.58ms 1.41ms 503.08ms 50 2.52s
:get-y 5 80.25μs 126.18μs 15.98μs 104.84μs 0 524.18μs
Clock Time 100 5.03s
Accounted Time 50 2.52s
Whereas this one realizes the lazy sequences inside the get-y profile:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(p :get-y (doall (get-y)))))
12037645987105892436354169872031089546721058729634=> nil
pId nCalls Min Max MAD Mean Time% Time
:get-x 5 502.54ms 504.71ms 705.6μs 503.5ms 50 2.52s
:get-y 5 501.69ms 505.68ms 1.05ms 503.06ms 50 2.52s
Clock Time 100 5.03s
Accounted Time 100 5.03s
This is important to know for the profiling experience, because when dealing with lazy sequences, you're realizing the performance of how they are used, not the sequences themselves:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(p ::realize-y
(doall (p :get-y (get-y))))))
06538947123410695278450678913223071958645126380479=> nil
pId nCalls Min Max MAD Mean Time% Time
:user/realize-y 5 503.29ms 504.86ms 458.12μs 504.37ms 50 2.52s
:get-x 5 500.13ms 505.06ms 1.4ms 503.64ms 50 2.52s
:get-y 5 86.0μs 1.15ms 331.81μs 322.94μs 0 1.61ms
Clock Time 100 5.04s
Accounted Time 100 5.04s

Related

Function doesn't print the integers inside her

I'm a begginer with clojure and i were reading a book that contained that function:
(defn illustrative-function [] (+ 1 304) 30 "joe")
And if you invoke that function without an argument it returns only "joe", as you can see:
(illustrative-function )
=> "joe"
My question:
Why the numbers inside the function aren't printed? 305 and 30? Even when i use and argument (and a parameter) it doesn't return nothing:
(defn illustrative-function [x] x (+ 1 304) 30 "joe")
=> #'dev-projects.core/illustrative-function
(illustrative-function 3)
=> "joe"
(illustrative-function [3])
=> "joe"
Can someone explain why does that happens?
Why the integers and the arguments are not printed?
Thanks!
The body of a defn is wrapped in an do. do allows you to execute
multiple instructions usually for side-effects. The last statement in
the do is the return. So this looks like this:
(defn illustrative-function
[]
(do
(+ 1 304) ; no-op
30 ; no-op
"joe")) ; return
(+ 1 304) is read and calculated, then thrown aways. 30 is just
read and thrown away. "joe" then is the return of do and by that
the return of the function.
If you want to "print" something, you have to explicitly print it.
E.g. replace 30 with (println 30). Also note, that in the REPL, the
return value is printed into the REPL - if you call that function from
somewhere else, nothing is printed unless you print explicitly.

List definition by repeated entry/iteration

I want to define the Thue-Morse Sequence (or the fair-sharing sequence) in terms of an initial element, 0, and the rule defining the next section of the list in terms of the entire list up until this point. i.e.
fair 0 = [0]
--fair 1 = [0,1]
--fair 2 = [0,1,1,0]
--fair 3 = [0,1,1,0,1,0,0,1]
fair n = fair (n - 1) ++ map (1-) (fair (n - 1))
This works fine to generate the list up to any predefined length, but it seems ineffective to not just define the entire list at once, and use take if I need a predefined amount.
My first attempt at defining the entire list was fair = 0 : map (1-) fair but of course, this populates the list as it goes, so it doesn't ever (need to) reenter the list (and returns [0,1,0,1,0,1...]). What I want is some way to define the list so that when it reaches a not-yet-defined element in the list, it defines the next 'chunk' by reentering the list only until that point, (rather than the computation 'chasing' the new values as they're produced), so the steps in computing the list would be akin to this procedure:
begin with initial list, [0]
map (1-) over the existing list, producing [1]
append this to the existing list, producing [0,1]
map (1-) over the existing list, producing [1,0]
append this to the existing list, producing [0,1,1,0]
map (1-) over the existing list, producing [1,0,0,1]
append this to the existing list, producing [0,1,1,0,1,0,0,1]
The Wikipedia article I linked above has a helpful gif to illustrate this process.
As I presume you can see, this would continue indefinitely as new elements are needed. However, I can't for the life of me find a way to successfully encode this in a recursive function.
I have tried
reenter f xs = reenter f (xs ++ map f xs)
fair = reenter (1-) [0]
But while the logic seems correct, it hangs without producing anything, probably due to the immediate recursive call (though I thought haskell's lazy evaluation might take care of that, despite it being a rather complex case).
As you noted, you can't do the recursive call immediately - you first need to return the next result, and then recursively call, as in your last try:
Prelude> reenter prev_list = inverted_prev_list ++ reenter (prev_list ++ inverted_prev_list) where inverted_prev_list = map (1-) prev_list
Prelude> f = [0] ++ reenter [0]
Prelude> take 20 f
[0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1]
Following is code in Racket, another functional programming language, using the steps listed in the question.
(define (f n)
(define (invert s) ; sub-function to invert the numbers
(list->string
(for/list ((i (string->list s)))
(if (equal? i #\0) #\1 #\0))))
(let loop ((c 1)
(s "0")) ; starting string is "0"
(if (> c n)
s
(loop (add1 c)
(string-append s (invert s))))))
Testing:
(f 1)
(f 2)
(f 3)
(f 4)
(f 5)
Output:
"01"
"0110"
"01101001"
"0110100110010110"
"01101001100101101001011001101001"
For infinite series:
(define (f)
(define (invert s)
(list->string
(for/list ((i (string->list s)))
(if (equal? i #\0) #\1 #\0))))
(let loop ((s "0"))
(define ss (string-append s (invert s)))
(println ss)
(loop ss)))
To run:
(f)
This may give some ideas regarding a Haskell solution to this problem.

How to check whether a value is fall into a range or not in clojure

The range could be defined by maxInclude, maxExclude,minInclude,minExclude
(defn check-range [value maxInclude maxExclude minInclude minExclude] ...)
And the following should hold true.
(check-range 100 100 nil nil 10) ;; should return true since 100<=100 and 100>10
(check-range 100 nil 200 nil 10) ;; should return true since 100<200 and 100>10
(check-range 100 100 nil 101 nil) ;; should return false since 100<=101 is not true
Is there any simple solution? I am using a long code which looks like imperative solution. I think in clojure there must be some nice solutions.
update: my code is as below, but not complete and need help to complete it
(defn check-range [value maxInclude maxExclude minInclude minExclude]
(
let [value1 (if (and maxInclude (< value maxInclude)) false true)
value2 (if (and maxExclude (<= value maxExclude)) false true)
value3 (if (and minInclude (> value minInclude)) false true)
value4 (if (and minExclude (>= value minExclude)) false true)
]
;;; then how to combine value1,2,3,4 into final result as false or true.
)
)
)
I'm not sure what it means for a range to have both an inclusive and exclusive maximum (or similarly, minimum). It seems like those options should be mutually exclusive, which suggests you shouldn't let clients opt into choosing both. Otherwise, how do you decide if it's more important for inclusion to win, or exclusion? The choice seems like it would have to be pretty arbitrary.
I suggest that it would be better to have a different way of constructing the range. This would have the additional benefit of avoiding all the nil hoops you're talking about jumping through and let users be explicit about the kind of range that they're making.
Perhaps something like:
(defn make-range-checker [bottom-check top-check]
(fn [n]
(and (bottom-check n)
(top-check n))))
So that for your initial 3 examples, you'd do something like these to create range-checking functions that you could apply to your input of 100:
(make-range-checker (partial < 10) (partial >= 100))
(make-range-checker (partial < 10) (partial > 200))
(make-range-checker (partial <= 100) (partial > 101))
(your third example is not correct, incidentally: "100<=101 is not true")
Someone wanting to create a range that extends to infinity in either direction could simply pass a predicate that always returns true.
(make-range-checker (partial < 10) (constantly true))
(make-range-checker (constantly true) (partial > 10))

Looking for a replace-in-string function in elisp

I'm looking for an equivalent of replace-regexp-in-string that just uses literal strings, no regular expressions.
(replace-regexp-in-string "." "bar" "foo.buzz") => "barbarbarbarbarbarbarbar"
But I want
(replace-in-string "." "bar" "foo.buzz") => "foobarbuzz"
I tried various replace-* functions but can't figure it out.
Edit
In return for the elaborate answers I decided to benchmark them (yea, I know all benchmarks are wrong, but it's still interesting).
The output of benchmark-run is (time, # garbage collections, GC time):
(benchmark-run 10000
(replace-regexp-in-string "." "bar" "foo.buzz"))
=> (0.5530160000000001 7 0.4121459999999999)
(benchmark-run 10000
(haxe-replace-string "." "bar" "foo.buzz"))
=> (5.301392 68 3.851943000000009)
(benchmark-run 10000
(replace-string-in-string "." "bar" "foo.buzz"))
=> (1.429293 5 0.29774799999999857)
replace-regexp-in-string with a quoted regexp wins. Temporary buffers do remarkably well.
Edit 2
Now with compilation! Had to do 10x more iteration:
(benchmark-run 100000
(haxe-replace-string "." "bar" "foo.buzz"))
=> (0.8736970000000001 14 0.47306700000000035)
(benchmark-run 100000
(replace-in-string "." "bar" "foo.buzz"))
=> (1.25983 29 0.9721819999999983)
(benchmark-run 100000
(replace-string-in-string "." "bar" "foo.buzz"))
=> (11.877136 86 3.1208540000000013)
haxe-replace-string is looking good
Try this:
(defun replace-in-string (what with in)
(replace-regexp-in-string (regexp-quote what) with in nil 'literal))
s.el string manipulation library has s-replace function:
(s-replace "." "bar" "foo.buzz") ;; => "foobarbuzz"
I recommend installing s.el from Emacs package manager, if you work with strings in your Elisp.
Emacs 28.1 (still in development at time of writing) provides this as standard:
** New function 'string-replace'.
This function works along the line of 'replace-regexp-in-string', but
matching on strings instead of regexps, and does not change the global
match state.
(string-replace FROMSTRING TOSTRING INSTRING)
Replace FROMSTRING with TOSTRING in INSTRING each time it occurs.
(string-replace ".*" "BAR" "foo.*bar.*baz")
⇒ "fooBARbarBARbaz"
I'd not hope for this to be faster:
(defun haxe-replace-string (string string-a string-b)
"Because there's no function in eLisp to do this."
(loop for i from 0 upto
(- (length string) (length string-a))
for c = (aref string i)
with alen = (length string-a)
with result = nil
with last = 0
do (loop for j from i below (+ i alen)
do (unless
(char-equal
(aref string-a (- j i))
(aref string j))
(return))
finally
(setq result
(cons (substring string last (- j alen)) result)
i (1- j) last j))
finally
(return
(if result
(mapconcat
#'identity
(reverse (cons (substring string last) result)) string-b)
string))))
Becasue replace-regexp-in-string is a native function, but you never know... Anyways, I wrote this some time ago for some reason, so, if you fill like comparing the performance - you are welcome to try :)
Another idea, using temporary buffer:
(defun replace-string-in-string (what with in)
(with-temp-buffer
(insert in)
(beginning-of-buffer)
(while (search-forward what nil t)
(replace-match with nil t))
(buffer-string)))
s-replace is fine if you are ready to require it, but say you want to use a replace in string feature early in the load process and don't yet have s.el loaded or don't need all of it. Well, here is the definition of s-replace from s.el. As you can see, it has no dependencies so you can use it without requiring the rest of s.el:
(defun s-replace (old new s)
"Replaces OLD with NEW in S."
(declare (pure t) (side-effect-free t))
(replace-regexp-in-string (regexp-quote old) new s t t))

Why does loop statement have uneven number of binding vectors?

I've been looking at examples and documentation; and I cannot figure out why I'm getting the
loop requires an even number of forms in binding vector error.
I believe the problem is in the loop and initializing usage-indicies. I just cannot figure out what I'm doing wrong.
(def usage-vec-len 13)
(defn ret-usage-indicies
"Takes a billed water consumption amount, and returns a vector of the ranges."
[reading]
(let [usage-indicies [0 0 0 0 0 0 0 0 0 0 0 0 0] curr-idx (- usage-vec-len 1)]
(loop [curr-reading reading ui usage-indicies curr-idx]
.
.
.
(if (= remaining-reading 0)
ui
(recur remaining-reading (assoc ui curr-idx curr-reading) (dec curr-idx)))))))
A loop form should look just like a let form. You can add comma whitespace for clarity:
(loop [symbol1 init1, symbol2 init2, ...] body-of-expressions)
It looks like you might want
(loop [curr-reading reading, ui usage-indicies, curr-idx curr-idx] ...)
where curr-index is initialized (rebound) to curr-index from the let expression.
Better, you could move the initialization you having going on in your let form down to the loop form itself. It also looks as if usage-vec-len is just the count of usage-indices, so no need to specify that in a global def when you can take care of that in the loop binding as well.
(loop [curr-reading reading
ui [0 0 0 0 0 0 0 0 0 0 0 0 0]
curr-idx (dec (count ui))]
body-of-expressions)