From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id D6B07BBAF for ; Mon, 23 Aug 2010 15:47:02 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ah8DALMYckxKfVIuimdsb2JhbACDF5AOjQEIFQEBAQoJDAcPBR+gBIhcPIIThgcuiFQBAQMFgR2DInMEiXY X-IronPort-AV: E=Sophos;i="4.56,257,1280700000"; d="scan'208";a="55919014" Received: from mail-ww0-f46.google.com ([74.125.82.46]) by mail3-smtp-sop.national.inria.fr with ESMTP; 23 Aug 2010 15:47:02 +0200 Received: by wwb24 with SMTP id 24so1072882wwb.3 for ; Mon, 23 Aug 2010 06:47:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:subject:date :user-agent:references:in-reply-to:mime-version:content-type :content-transfer-encoding:message-id; bh=eqHxeyz0Dav0+fpU3/xLHEi8SgKKCQPA9f+qDIla7sY=; b=XEjMdpXgVHsrrVsAa7kCR20EfVmcWL9eWStpc0xZ9pgNr7EskLBvHIQf4tvG6FVpe8 PUlMRIeNwiNgh2oLq/bx1+qHlIf5fWn/DkVU7NyI432add9ur1VKkO/c4ZqfiWkMxAAE 1fzdxseWfZ/z+A6idjEOB3Dw+7coCs5Vyzxnw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:date:user-agent:references:in-reply-to:mime-version :content-type:content-transfer-encoding:message-id; b=PPgUARzi5E6vuJhT2yelzI4G9O5LRNHne0Gjpc5Bq0lV6hcgKOr/C5lq9NNz2D9FR8 uMxa2rRty7V2QSPsNg3fh0DhorLRVJhviZO2hf9i90mbbqdx8r93EttM4cZ2SCA74D/x aeGLIMC3Rl5EWUn7t7FWogkx1OaAAtwm2e2tU= Received: by 10.227.134.194 with SMTP id k2mr4512261wbt.86.1282571222134; Mon, 23 Aug 2010 06:47:02 -0700 (PDT) Received: from localhost.localnet (pat35-5-78-226-58-147.fbx.proxad.net [78.226.58.147]) by mx.google.com with ESMTPS id w31sm3885801wbd.3.2010.08.23.06.47.01 (version=SSLv3 cipher=RC4-MD5); Mon, 23 Aug 2010 06:47:01 -0700 (PDT) From: Florent Monnier To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] caml_copy_string Date: Mon, 23 Aug 2010 15:46:54 +0200 User-Agent: KMail/1.13.3 (Linux/2.6.33.5-desktop586-2mnb; KDE/4.4.3; i686; ; ) References: <201008231409.06024.monnier.florent@gmail.com> <4C7270A7.4070803@crans.org> In-Reply-To: <4C7270A7.4070803@crans.org> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201008231546.54860.monnier.florent@gmail.com> X-Spam: no; 0.00; ocaml:01 ocaml:01 buffer:01 allocations:01 buffer:01 pointer:01 bigarrays:01 ocamlopt:01 bigarray:01 cmxa:01 stub:01 mlvalues:01 alloc:01 bigarray:01 const:01 Le lundi 23 ao=C3=BBt 2010 14:59:19, St=C3=A9phane Glondu a =C3=A9crit : > Le 23/08/2010 14:09, Florent Monnier a =C3=A9crit : > >> 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? > >=20 > > an alternative method is to provide a string from ocaml to c then c fil= ls > > this buffer, then you can save allocations by reusing the same buffer, > > see: [...] >=20 > 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=20 $ 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D #include #include #include #include #include static const char *str =3D "the walking camel"; static const int len =3D 18; CAMLprim value ml_mystr1(value unit) { return caml_copy_string(str); } CAMLprim value ml_mystr2(value ml_buf) { int buf_len =3D 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] =3D 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 =3D caml_ba_byte_size(Caml_ba_array_val(ba)); if (len > ba_size) caml_failwith("buffer overflow"); ptr =3D Caml_ba_data_val(ba); memcpy(ptr, str, len); return Val_int(len); } =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D external mystr1: unit -> string =3D "ml_mystr1" external mystr2: string -> int =3D "ml_mystr2" "noalloc" type ba_string =3D (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t external mysba1: unit -> ba_string =3D "ml_mysba1" external mysba2: ba_string -> int =3D "ml_mysba2" "noalloc" let n =3D 1_000_000_000 let test1() =3D for i =3D 1 to n do let _ =3D mystr1 () in () done let test2() =3D let buf =3D String.create 100 in for i =3D 1 to n do let _ =3D mystr2 buf in () done let test3() =3D for i =3D 1 to n do let _ =3D mysba1 () in () done let test4() =3D let bstr =3D Bigarray.Array1.create Bigarray.char Bigarray.c_layout 100 in for i =3D 1 to n do let _ =3D mysba2 bstr in () done let () =3D match Sys.argv.(1) with | "1" -> test1() | "2" -> test2() | "3" -> test3() | "4" -> test4() | _ -> assert false =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-=20 Regards =46lorent