Clojure write to map vs doseq file

I need to write material to a file based on the elements of the Clojure collection, which I can do, but I came across something that confuses me. Probably because I do not fully understand the time macro, but when I do the following:

=> (def nums (take 100000 (repeatedly #(str (rand-int 1000) " ")))) (defn out1 [nums] (doseq [n nums] (spit "blah1.txt" n :append true))) (defn out2 [nums] (map #(spit "blah2.txt" % :append true) nums)) #'test.core/nums #'test.core/out1 #'test.core/out2 => (time (out1 nums)) "Elapsed time: 19133.247 msecs" nil => (time (out2 nums)) "Elapsed time: 0.209 msecs" (nil nil nil nil ... ) 

implementation using map (out2) is much faster. However, when I go to the folder and look at the file, it continues to write after the Elapsed Time has expired, and the output (nil ...) waits until it records to show as well. It makes me think that they both actually take the same time.

So what is the difference between using a dose and a map in this situation? And how would it be better overall? Thanks

+4
source share
1 answer

the dose is impatient (not lazy) and does all the work when you call it. The map is lazy and immediately returns a lazy sequence representing the work that will be performed when reading the result.

therefore, the card does the work when the replica displays the result on the card (all nilds) not on the part where you are. to fix this, call doall or dorun around the map call.

 (time (doall (out2 nums))) 

the more significant error is that you do not print the result (or otherwise destroy it), then the contents will not be written to the file at all. In general, for purely side- doseq operations, probably the best choice.

+3
source

Source: https://habr.com/ru/post/1492792/


All Articles