From: Michal Moskal <malekith@pld-linux.org>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Array.filter
Date: Mon, 11 Aug 2003 11:46:04 +0200 [thread overview]
Message-ID: <20030811094604.GA6433@roke.freak> (raw)
In-Reply-To: <00c601c35f81$c2f59480$a45afac1@zofo>
On Sun, Aug 10, 2003 at 10:55:36PM +0200, Jean-Baptiste Rouquier wrote:
> let filter test a =
> let result = (Array.fold_left
> (fun accu elt ->
> if test elt then elt :: accu else accu)
> [] a) in
> Array.of_list (List.rev result)
I did some timing for several versions.
1% elements selected:
0 0.26s real 0.21s user 0.01s system
1 0.46s real 0.37s user 0.01s system
2 1.18s real 0.85s user 0.06s system
3 0.92s real 0.66s user 0.10s system
4 0.57s real 0.43s user 0.03s system
5 0.52s real 0.44s user 0.00s system
1/2 elements selected:
0 0.29s real 0.19s user 0.03s system
1 2.53s real 2.04s user 0.10s system
2 1.49s real 1.05s user 0.11s system
3 1.31s real 0.98s user 0.12s system
4 8.55s real 6.87s user 0.10s system
5 1.48s real 1.15s user 0.05s system
0. just create random array, substract from subseqent results
1. version posted by Qrczak, allocates space on the heap
2. allocate bool array for predicate results
3. allocate array, and then sub it
4. your version
5. allocate first 32 elemnts for results, when it's filled, store array
on list, allocate 64 and so on. At the end concat resulting arrays.
5. version doesn't seem to have worst case (it's slower then fastest
versions in given situation, but not by much).
#v+
let filter1 pred arr =
let sz = Array.length arr in
if sz == 0 then arr else
let rec loop i j =
if i >= sz then Array.make j arr.(0) else
let x = arr.(i) in
if pred x then begin
let result = loop (i + 1) (j + 1) in
result.(j) <- x;
result
end else loop (i + 1) j in
loop 0 0
let filter2 f ar =
let sz = Array.length ar in
if sz == 0 then ar else
let tmp = Array.create sz false in
let rec loop len i =
if i >= sz then len
else
if f ar.(i) then
(tmp.(i) <- true; loop (len + 1) (i + 1))
else
loop len (i + 1)
in
let len = loop 0 0 in
let res = Array.create len ar.(0) in
let rec loop len i =
if i >= sz then res
else
if tmp.(i) then
(res.(len) <- ar.(i); loop (len + 1) (i + 1))
else
loop len (i + 1)
in loop 0 0
let filter3 f ar =
let sz = Array.length ar in
if sz == 0 then ar else
let tmp = Array.create sz ar.(0) in
let rec loop len i =
if i >= sz then
Array.sub tmp 0 len
else
if f ar.(i) then
(tmp.(len) <- ar.(i); loop (len + 1) (i + 1))
else
loop len (i + 1)
in loop 0 0
let filter4 test a =
let result = (Array.fold_left
(fun accu elt ->
if test elt then elt :: accu else accu)
[] a)
in Array.of_list (List.rev result)
let filter5 f ar =
let sz = Array.length ar in
if sz == 0 then ar else
let rec loop acc cur i pos =
if i >= sz then
if pos == 0 then
Array.concat (List.rev acc)
else
let cut = Array.sub cur 0 pos in
Array.concat (List.rev (cut :: acc))
else
if pos >= Array.length cur then
loop (cur :: acc) (Array.make (Array.length cur * 2) ar.(0)) i 0
else
if f ar.(i) then
(cur.(pos) <- ar.(i); loop acc cur (i + 1) (pos + 1))
else
loop acc cur (i + 1) pos
in
loop [] (Array.make 32 ar.(0)) 0 0
let main () =
let ar = Array.init 1000000 (fun _ -> Random.int 100) in
let test f =
for i = 1 to 10 do
Printf.printf "%d\n" (Array.length (f (fun x -> x > 50) ar))
done
in
match Sys.argv.(1) with
| "0" -> ()
| "1" -> test filter1
| "2" -> test filter2
| "3" -> test filter3
| "4" -> test filter4
| "5" -> test filter5
| _ -> assert false
;;
main ()
#v-
--
: Michal Moskal :: http://www.kernel.pl/~malekith : GCS {C,UL}++++$ a? !tv
: When in doubt, use brute force. -- Ken Thompson : {E-,w}-- {b++,e}>+++ h
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
next prev parent reply other threads:[~2003-08-11 9:48 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-07 19:41 [Caml-list] Multi-keyed lookup table? Matt Gushee
2003-08-07 20:16 ` Brian Hurt
2003-08-07 21:49 ` Yaron Minsky
2003-08-07 22:26 ` John Max Skaller
[not found] ` <D4DBD8568F05D511A1C20002A55C008C11AC05E6@uswaumsx03medge.med.ge.com>
2003-08-08 21:30 ` Matt Gushee
2003-08-08 22:13 ` Brian Hurt
[not found] ` <005d01c35e51$7c927200$6628f9c1@zofo>
2003-08-09 16:57 ` [Caml-list] Array.filter (was Multi-keyed lookup table?) Matt Gushee
2003-08-09 18:48 ` ijtrotts
2003-08-10 19:53 ` Michal Moskal
2003-08-10 2:34 ` ijtrotts
2003-08-11 5:48 ` David Brown
2003-08-10 18:53 ` ijtrotts
2003-08-10 20:23 ` Marcin 'Qrczak' Kowalczyk
2003-08-10 2:37 ` ijtrotts
[not found] ` <200308102222.16369.qrczak@knm.org.pl>
2003-08-10 20:43 ` Michal Moskal
2003-08-10 21:59 ` Ville-Pertti Keinonen
2003-08-10 20:55 ` [Caml-list] Array.filter Jean-Baptiste Rouquier
2003-08-11 9:46 ` Michal Moskal [this message]
2003-08-10 22:29 ` [Caml-list] Array.filter (was Multi-keyed lookup table?) Shawn Wagner
2003-08-11 11:51 ` [Caml-list] Multi-keyed lookup table? Remi Vanicat
2003-08-07 22:19 ` John Max Skaller
2003-08-12 6:34 ` Florian Hars
2003-08-12 9:58 ` Michael Wohlwend
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=20030811094604.GA6433@roke.freak \
--to=malekith@pld-linux.org \
--cc=caml-list@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