Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Ormente

#1
Hi Lutz,



Sometimes REGEX are too slow for simple things that could be better done with the scan, the "inverse" of format.



Do you think it could be possible to have a scan function in newlisp, or have you an alternative to suggest ?



Thanks
#2
Hi!



I was playing lately with this :
#!/usr/bin/newlisp -n -c

(context 'pool)

(define (pool:pool task (poolSize 5) (syncDelay 50))
    (while (> (length (sync)) poolSize)
         (sync syncDelay))
    (spawn 's (eval task)))


(define (pool:map task liste (poolSize 5) (syncDelay 50))
    (let (size (- (length liste) 1)
          out  '())
        ; spawn processes
        (for (i 0 size)
            ; Wait for availlable "slot" in pool
            (while (>= (length (sync)) poolSize)
                 (sync syncDelay))
            (spawn (sym i) (task (liste i))))
        (sync 10000)
        ; get back values
        (for (i 0 size)
            (push (eval (sym i)) out -1))))


(context 'MAIN)

(define (test-func x)
    (sleep (+ 5 (rand 100)))
    (* x x))

(println
    "Map without pooling : "
    (time (map test-func (sequence 1 100)))
    "ms")

(println
    "Pool map, default pool size : "
    (time (pool:map test-func (sequence 1 100)))
    "ms")

(println
    "Pool:map, pool size = 50 : "
    (time (pool:map test-func (sequence 1 100) 50))
    "ms")

(println
    "Just to check results : "
    (pool:map test-func (sequence 1 100) 50))

(println
    "Pool:map on string : "
    (join (pool:map (lambda (c) (upper-case c)) "A beautiful string") "") )

(exit)


Very basic attempt at creating higher level functions for multiprocessing. I thought it could be a good thing to have functions similar to these two (more optimised and fault-tolerant) availlable in newlisp coore:

- a pool-map to map a function on a list (or more, but my attempt is one list only) in a parallel way.

- a pool-pool to distribute tasks in a loop on a pool of threads (for side effects only, as in my attempt results are discarded).



What do you think?
#3
Just remove the call to print.
#4
Thanks Lutz.

The best keeps getting better...
#5
newLISP in the real world / Re: threadring in newlisp
September 21, 2011, 12:44:49 AM
Thanks a lot Lutz.



I spent some time rewriting my code with your idea (not waiting for the result, and letting threads end themselves), but conforming to the benchmark specification, and the best i can get is :


#!/usr/bin/newlisp

(set 'nThreads  503
     'limit     500000
     'channels  '())

; The worker code
(define (worker id chanR chanW , r)
    (while (< r limit)
        (write-line chanW (string (+ 1 (set 'r (int (read-line chanR)))))))
    (when (= r limit) (println "Done by id:" id))
)

; make communication channels
(dotimes (i nThreads) (push (pipe) channels))

; spawn workers
(dotimes (i nThreads)
    (let (  id (+ i 1)
            in (channels i 0)
            out (channels (% (+ 1 i) nThreads) 1) )
        (spawn 'p (worker id in out))))


(set 'start (time-of-day))
; put the token in the ring
(write-line ((channels 0) 1) "0")
; wait for threads end
(until (sync 10))

(println "Duration: " (- (time-of-day) start) "ms")

(exit)


That's a bit better (about 15-20% faster) but still a lot slower than the slowest code from the Alioth benchmark, in wich i think some languages use real processes too. I wonder if the difference is not more in pipe readwriting than in process switching.



BTW that's fast enough for me, and even if one allways want improvements, i think overall newLISP is realy a briliant piece of software.
#6
newLISP in the real world / threadring in newlisp
September 20, 2011, 11:45:27 AM
I tried to implement the threadring task from http://shootout.alioth.debian.org/u32/performance.php?test=threadring">the alioth language benchmark, and found my code very slow. It's my first atempt at "multithreading", so i hope someone can help me to make it faster.



Here is my code :



(set 'nThreads  503
     'limit     500000
     'channels  '())

; worker do that
(define (worker id chanR chanW , r)
  (catch
      (while (set 'r (int (read-line chanR)))
          (if (= r limit)
              (throw id)
              (write-line chanW (string (inc r)))))
  )
)

; make communication channels
(for (i 0 nThreads) (push (pipe) channels -1))

; spawn workers
(for (i 0 nThreads)
    (spawn 'p (worker (+ i 1)
                  ((channels i) 0)
                  ((channels (% (+ 1 i) nThreads)) 1) )) )

; start the process by giving the token to first thread
(write-line ((channels 0) 1) "0")

; wait for result
(while (not p) (sleep 100) (sync 1))

(println "DONE BY " p)

(abort)

(exit)


It's slower than all the other implementations, newlisp can do better.



Thanks for your help.



Renaud.
#7
newLISP newS / Re: LUA OR Newlisp
July 20, 2011, 03:27:37 AM
Lua is "just a language", with far less features and capabilities right out of the box. It's a nice one, but you quickly need to install extensions and libraries. There are lot of them availlable, but that make lua less portable, and harder to manage. On the other side, newlisp is feature rich, and easier for distributing your scripts, as in most case a simple fresh install provide all you need to run your scripts.



Next you have to chose from "algol style" syntax (lua) or lisp syntax... it's (mainly but not only) a matter of taste.



Finaly, if you intend to script some existing application, the scripting language is no more a choice : renoise use lua, blender use python... and so on...
#8
nice move ;-)



I tried something similar, but keeping "sort l" made it nearly the same speed as do-it.



Whithout the sort, you're faster. You don't get the exact same output (not a list), but having the result in a hashtable make accessing individual sublists fast and easy. Cool.
#9
Yes, Sherlock, that's so true !



Thanks for the dataset.
#10
newLISP in the real world / Re: This week's challenge
February 28, 2011, 10:46:44 PM
Cool :-)



I started initialy by doing it "lispishly", but it apears to be extremely ineficient (but more elegant), due do a lot of copies newlisp have to make and carry along :

(define (heads l)
(unique (map first l))
)

(define (members l class)
(filter (fn (x) (= class (first x))) l)
)

(define (doit l)
(map (fn (c) (members l c)) (heads l))
)


So, i still thinks newlisp is pragmatic, practical and useful, and allow elegant "functional style" solutions, but it is often far far more efficient when doing things in the "imperative style". I like it, but like Haskell too ;-)



BTW, would you mind sharing your test list ?
#11
newLISP in the real world / Re: This week's challenge
February 28, 2011, 08:43:42 AM
here's my code :



(define (do-it l , acc p c)
(setf
acc '()
p -1
c   ""
)
(dolist (i (sort l))
(when (!= c (first i))
(setf c (first i))
(inc p)
(push '() acc -1)
)
(push i (acc p) -1)
)
acc
)


How does it perform against your big list ?
#12
newLISP in the real world / Re: event system
January 29, 2011, 09:09:58 AM
A little better :



(define-macro (with-events _todo_)
(let (_fun_ (string (_todo_ 0)) _res_ nil)
(eval (EVENTS-BEFORE _fun_))
(setf _res_ (eval _todo_))
(eval (EVENTS-AFTER _fun_))
_res_
)
)


This way, i can do :



> (event-before + (setf (_todo_ 2) 100))
> (with-events (+ 4 5 6))
110
> (event-after + (println "args : " (rest _todo_)))
> (with-events (+ 4 5 6))
args : (4 100 6)
110
#13
newLISP in the real world / event system
January 29, 2011, 08:06:10 AM
I'm exploring ways to add some sort of events in the flow of a script... i would like to have your opinion about how to do this, and how i've done it. Here's my first take with this idea :

(new Tree 'EVENTS-BEFORE)
(new Tree 'EVENTS-AFTER)

(define-macro (event-before target action)
(setf target (string target))
(unless (EVENTS-BEFORE target) (EVENTS-BEFORE target '(begin)) )
(extend (EVENTS-BEFORE target) (list action))
)

(define-macro (event-after target action)
(setf target (string target))
(unless (EVENTS-AFTER target) (EVENTS-AFTER target '(begin)) )
(extend (EVENTS-AFTER target) (list action))
)

(define-macro (with-events)
(let (_fun_ (string (args 0)) _res_ nil)
(eval (EVENTS-BEFORE _fun_))
(setf _res_ (eval $args))
(eval (EVENTS-AFTER _fun_))
_res_
)
)


With this, i can do that :



;; for now, same as (+ 4 5 6)
> (with-events + 4 5 6)
15
;; add a new "before" add event
> (event-before + (println "will add something : " $args))
;; then an "after" event
> (event-after + (println "done!"))
;; then, if i call "+" with events :
> (with-events + 4 5 6)
will add something : (+ 4 5 6)
done!
15

Is there a more idiomatic way to do this ?

Any idea to make it better (something like a way for "before" events to change the args, for example ) ?





EDIT : some background about why i want do do this. For my web framework, the main cgi script is very simple, and should end with something like "(output)". This function will output the headers, and the content. Clean and simple.

But along the way i may have loaded a module to provide sessions, and another to access a database. So, i want these modules to be able to gracefully save the session and disconnect from the database at the end of the script, without having to invoque the coresponding function explicetly. The idea :

;; in my framework :
(define (output)
(with-events output-headers)
(with-events output-content)
)

;; in a session handling extension
(event-before output-headers (SESSION:save))

;; in a text formater extension
(event-before output-content (TYPOGRAPHIST:reformat-all))

;; somwhere else
(event-after output-content (LOGGER:do-something))
#14
newLISP in the real world / newLISP on android ?
October 07, 2010, 07:55:14 AM
I played with http://code.google.com/p/android-scripting/">ASE, mainly with the Lua interpreter, and found it pretty cool!

I wondered if it could be possible to have newLISP availlable as a scripting engine for ASE.



Someone know how to do that ?



EDIT : found this doc (http://code.google.com/p/android-scripting/wiki/InterpreterDeveloperGuide">http://code.google.com/p/android-script ... loperGuide">http://code.google.com/p/android-scripting/wiki/InterpreterDeveloperGuide) but a bit esoteric to me.
#15
I'm a noob, but i would say that "(random 10 5)" is random but not unique, so it can happens that you get the same key twice or more.