caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Compile-time performance problem
@ 2016-11-07 17:01 Christoph Höger
  2016-11-07 17:07 ` Christoph Höger
  0 siblings, 1 reply; 7+ messages in thread
From: Christoph Höger @ 2016-11-07 17:01 UTC (permalink / raw)
  To: caml users


[-- Attachment #1.1.1: Type: text/plain, Size: 2503 bytes --]

Dear all,

I have some (autogenerated) code that (naively) implements a function in
CPS.

To give you an idea: continuations are wrapped in objects with a
_continue_ field. Functions take an argument k, which is the next
continuation and s, which depicts a monadic state.

The whole file is generated from the following input:

let foo = do
    put 1 ;
    put 2 ;
    put 3 ;
    put 4 ;
    put 5 ;
    put 6 ;
    put 7 ;
    put 8

Here, put n means: Set the monadic state to n. The semicolon is
interpreted as the monadic bind operator (without actually binding a
variable in that simple case). Due to the cps nature, I compile as
follows (compilation in brackets [| .. |]):

[| m1 ; m2 |] =^=

(fun k s -> [|m1|] (object val _continue_ fun x -> [|m2|]; ... end)

(The with_continue and continue methods are intended to mimic structural
records)

When I compile to bytecode, it just works (TM). When I compile to
machine-code, the compilation time grows very fast:

choeger@oxide /tmp % ocamlopt -dtimings perf.ml
all: 1.284s
parsing(perf.ml): 0.001s
typing(perf.ml): 0.012s
transl(perf.ml): 0.011s
generate(perf.ml): 1.238s
cmm(sourcefile(perf.ml)): 0.000s
compile_phrases(sourcefile(perf.ml)): 0.042s
selection(sourcefile(perf.ml)): 0.005s
comballoc(sourcefile(perf.ml)): 0.000s
cse(sourcefile(perf.ml)): 0.003s
deadcode(sourcefile(perf.ml)): 0.001s
spill(sourcefile(perf.ml)): 0.006s
split(sourcefile(perf.ml)): 0.002s
liveness(sourcefile(perf.ml)): 0.005s
regalloc(sourcefile(perf.ml)): 0.016s
linearize(sourcefile(perf.ml)): 0.000s
scheduling(sourcefile(perf.ml)): 0.000s
emit(sourcefile(perf.ml)): 0.003s
assemble(sourcefile(perf.ml)): 0.000s
selection(startup): 0.002s
comballoc(startup): 0.000s
cse(startup): 0.001s
deadcode(startup): 0.000s
spill(startup): 0.002s
split(startup): 0.001s
liveness(startup): 0.002s
regalloc(startup): 0.006s
linearize(startup): 0.000s
scheduling(startup): 0.000s
emit(startup): 0.001s
assemble(startup): 0.000s


The generate part is the culprit. Is there any known performance
regression in 4.03.0 that could explain this? Is it the (admittedly
naive) style of the continuations that causes this?

thanks,

Christoph
-- 
Christoph Höger

Technische Universität Berlin
Fakultät IV - Elektrotechnik und Informatik
Übersetzerbau und Programmiersprachen

Sekr. TEL12-2, Ernst-Reuter-Platz 7, 10587 Berlin

Tel.: +49 (30) 314-24890
E-Mail: christoph.hoeger@tu-berlin.de

[-- Attachment #1.1.2: perf.ml --]
[-- Type: text/plain, Size: 4302 bytes --]

let (<+) a v = Array.append a [|v|] 
let foo k s =
  ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 1)
     (object (self)
        val _continue_ =
          fun x  ->
            (fun k  ->
               fun s  ->
                 ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 2)
                    (object (self)
                       val _continue_ =
                         fun x  ->
                           (fun k  ->
                              fun s  ->
                                ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 3)
                                   (object (self)
                                      val _continue_ =
                                        fun x  ->
                                          (fun k  ->
                                             fun s  ->
                                               ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 4)
                                                  (object (self)
                                                     val _continue_ =
                                                       fun x  ->
                                                         (fun k  ->
                                                            fun s  ->
                                                              ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 5)
                                                                 (object (self)
                                                                    val _continue_ =
                                                                    fun x  ->
                                                                    (fun k  ->
                                                                    fun s  ->
                                                                    ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 6)
                                                                    (object (self)
                                                                    val _continue_ =
                                                                    fun x  ->
                                                                    (fun k  ->
                                                                    fun s  ->
                                                                    ((fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 7)
                                                                    (object (self)
                                                                    val _continue_ = fun x  -> (fun k  -> fun s  -> (k#_continue_ (object (self)  end)) 8) k
                                                                    method with__continue_ x = {<_continue_ = x>}
                                                                    method _continue_ = _continue_
                                                                    end)) s) k
                                                                    method with__continue_ x = {<_continue_ = x>}
                                                                    method _continue_ = _continue_
                                                                    end)) s) k
                                                                    method with__continue_ x = {<_continue_ = x>}
                                                                    method _continue_ = _continue_
                                                                  end)) s) k
                                                     method with__continue_ x = {<_continue_ = x>}
                                                     method _continue_ = _continue_
                                                   end)) s) k
                                      method with__continue_ x = {<_continue_ = x>}
                                      method _continue_ = _continue_
                                    end)) s) k
                       method with__continue_ x = {<_continue_ = x>}
                       method _continue_ = _continue_
                     end)) s) k
        method with__continue_ x = {<_continue_ = x>}
        method _continue_ = _continue_
      end)) s
  

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-11-08 10:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-07 17:01 [Caml-list] Compile-time performance problem Christoph Höger
2016-11-07 17:07 ` Christoph Höger
2016-11-07 17:18   ` Nicolas Ojeda Bar
2016-11-07 17:32     ` Christoph Höger
2016-11-08  8:56       ` Christoph Höger
2016-11-08 10:10         ` Goswin von Brederlow
2016-11-08 10:49           ` [Caml-list] <SPAM> " Pierre Chambart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).