Browse thread
Average cost of the OCaml GC
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | ygrek <ygrekheretix@g...> |
| Subject: | Re: [Caml-list] Average cost of the OCaml GC |
On Fri, 12 Nov 2010 12:27:40 -0500
Jianzhou Zhao <jianzhou@seas.upenn.edu> wrote:
> Do we still have other methods to debug such problems? Is it possible
> to know when and where GC runs, say, the number of times GC works
> after a particular usr-defined function? If this is possible, I was
> wondering if we can see which function in my code behave wrong.
Below is straghtforward "GC diffing" code which helps me to pinpoint excessive GC
(like the ExtLib.String.nsplit in example).
$ cat a.ml
open Printf
open Gc
let bytes_string_f f = (* oh ugly *)
let a = abs_float f in
if a < 1024. then sprintf "%dB" (int_of_float f) else
if a < 1024. *. 1024. then sprintf "%dKB" (int_of_float (f /. 1024.)) else
if a < 1024. *. 1024. *. 1024. then sprintf "%.1fMB" (f /. 1024. /. 1024.) else
sprintf "%.1fGB" (f /. 1024. /. 1024. /. 1024.)
let bytes_string x = bytes_string_f (float_of_int x)
let caml_words_f f =
bytes_string_f (f *. (float_of_int (Sys.word_size / 8)))
let caml_words x = caml_words_f (float_of_int x)
let gc_diff st1 st2 =
let allocated st = st.minor_words +. st.major_words -. st.promoted_words in
let a = allocated st2 -. allocated st1 in
let minor = st2.minor_collections - st1.minor_collections in
let major = st2.major_collections - st1.major_collections in
let compact = st2.compactions - st1. compactions in
let heap = st2.heap_words - st1.heap_words in
sprintf "allocated %10s, heap %10s, collection %d %d %d" (caml_words_f a) (caml_words heap) compact major minor
let gc_show name f x =
let st = Gc.quick_stat () in
Std.finally (fun () -> let st2 = Gc.quick_stat () in
eprintf "GC DIFF %s : %s\n" name (gc_diff st st2)) f x
let () =
let _ = gc_show "split" (ExtLib.String.nsplit (String.make 10000 'a')) "a" in
gc_show "compact" Gc.compact ()
$ ocamlfind ocamlopt -linkpkg -package extlib a.ml -o a
$ ./a
GC DIFF split : allocated 48.1MB, heap 48.0MB, collection 0 21 373
GC DIFF compact : allocated 240B, heap -48.0MB, collection 1 2 0
--
ygrek
http://ygrek.org.ua