From: Florent Monnier <monnier.florent@gmail.com>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] caml_copy_string
Date: Mon, 23 Aug 2010 15:46:54 +0200 [thread overview]
Message-ID: <201008231546.54860.monnier.florent@gmail.com> (raw)
In-Reply-To: <4C7270A7.4070803@crans.org>
Le lundi 23 août 2010 14:59:19, Stéphane Glondu a écrit :
> Le 23/08/2010 14:09, Florent Monnier a écrit :
> >> Is there a way to get a string from C to OCaml without the
> >> caml_copy_string function, or is there a version that doesn't copy the
> >> string?
> >
> > an alternative method is to provide a string from ocaml to c then c fills
> > this buffer, then you can save allocations by reusing the same buffer,
> > see: [...]
>
> You can also wrap your C pointer into bigarrays.
with a ba buffer speed is close than with a string buffer
but with ba allocs it is very slow:
$ ocamlopt -o test.opt bigarray.cmxa main.ml main_stub.c
$ time ./test.opt 1
44 seconds elapsed
$ time ./test.opt 2
21 seconds elapsed
$ time ./test.opt 3
3 minutes 28 seconds elapsed
(208 seconds elapsed)
$ time ./test.opt 4
25 seconds elapsed
========================
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <caml/fail.h>
#include <caml/bigarray.h>
static const char *str = "the walking camel";
static const int len = 18;
CAMLprim value ml_mystr1(value unit) {
return caml_copy_string(str);
}
CAMLprim value ml_mystr2(value ml_buf) {
int buf_len = caml_string_length(ml_buf);
if (len > buf_len) caml_failwith("buffer overflow");
memcpy(String_val(ml_buf), str, len);
return Val_int(len);
}
CAMLprim value ml_mysba1(value unit) {
long dims[3];
dims[0] = len;
return caml_ba_alloc(CAML_BA_UINT8 | CAML_BA_C_LAYOUT, 1, NULL, dims);
}
CAMLprim value ml_mysba2(value ba) {
unsigned char *ptr;
int ba_size = caml_ba_byte_size(Caml_ba_array_val(ba));
if (len > ba_size) caml_failwith("buffer overflow");
ptr = Caml_ba_data_val(ba);
memcpy(ptr, str, len);
return Val_int(len);
}
========================
external mystr1: unit -> string = "ml_mystr1"
external mystr2: string -> int = "ml_mystr2" "noalloc"
type ba_string =
(char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
external mysba1: unit -> ba_string = "ml_mysba1"
external mysba2: ba_string -> int = "ml_mysba2" "noalloc"
let n = 1_000_000_000
let test1() =
for i = 1 to n do
let _ = mystr1 () in ()
done
let test2() =
let buf = String.create 100 in
for i = 1 to n do
let _ = mystr2 buf in ()
done
let test3() =
for i = 1 to n do
let _ = mysba1 () in ()
done
let test4() =
let bstr = Bigarray.Array1.create Bigarray.char Bigarray.c_layout 100 in
for i = 1 to n do
let _ = mysba2 bstr in ()
done
let () =
match Sys.argv.(1) with
| "1" -> test1()
| "2" -> test2()
| "3" -> test3()
| "4" -> test4()
| _ -> assert false
========================
--
Regards
Florent
next prev parent reply other threads:[~2010-08-23 13:47 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-21 23:30 caml_copy_string Jeffrey Barber
2010-08-21 23:42 ` [Caml-list] caml_copy_string Romain Beauxis
2010-08-21 23:46 ` Mathias Kende
2010-08-22 17:16 ` Till Varoquaux
2010-08-23 0:42 ` Till Varoquaux
2010-08-23 1:02 ` Jeffrey Barber
2010-08-23 12:09 ` Florent Monnier
2010-08-23 12:59 ` Stéphane Glondu
2010-08-23 13:46 ` Florent Monnier [this message]
2010-08-23 20:24 ` Romain Beauxis
2010-08-24 14:21 ` Florent Monnier
2010-08-24 14:52 ` Till Varoquaux
2010-08-24 15:22 ` Anil Madhavapeddy
2010-08-24 15:35 ` Romain Beauxis
2010-08-25 19:16 ` Florent Monnier
2010-08-25 19:33 ` Romain Beauxis
2010-08-25 15:21 ` Goswin von Brederlow
-- strict thread matches above, loose matches on Subject: below --
2005-10-29 0:24 Jonathan Roewen
2005-10-29 0:32 ` Robert Roessler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201008231546.54860.monnier.florent@gmail.com \
--to=monnier.florent@gmail.com \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox