<noah>
hey everyone. i am brand-new to ocaml, and i've just re-implemented an algorithm in ocaml that was originally written in python. i did so hoping to see a significant speed increase. unfortunately, it is running, much, much slower. i've gone over it as best i can, but i really can't see what is taking so long. my guess is i'm missing something fundamental to ocaml programming techniques.
<noah>
if anyone cares to take a look, it's here: http://snipt.org/krh. you can click the magnifying class to expand the code window. it's a little over 200 lines, but the problem area is in just a couple of functions
<mrvn>
do you append to a list?
<noah>
i do using the :: operator. i was doing it using @ [single element], but i did some testing and found that that was a big time sink
<mrvn>
:: is fine, @ is usualy bad.
<mrvn>
List.nth is bad in add_ret.
<noah>
how come, out of curiosity?
<noah>
how else can you tokenize a line using commas as delimters and get the 4th?
<mrvn>
let add_ret line = let toks = String.nsplit line "," in match toks with [date; ticker; ret] in Hashtbl.add rets_table date (ticker, float_of_string ret)
<mrvn>
[date; ticker; _; ret] I mean.
<mrvn>
or date::ticker::_::ret::_
<noah>
ok, got it. that can't be a big slowdown tho, right? but it certainly looks a lot better
<noah>
the issue is in init_scores, line 207
<mrvn>
List.nth has to go through the list item by item. Not a huge effort for 0/1/3 but some.
<noah>
well, it's a linked list, underneath, right? so even using the better style, it's goign to be O(length of list), right?
<mrvn>
noah: but only once. Not once per item.
<noah>
mrvn: ahhh, right, good point. should have seen that ;)
<mfp>
noah: it's late here and there's a fair amount of code, but...
<mfp>
ExtString.String.nsplit is O(n^2) on the string length IIRC
<mfp>
actually, the num of substrings
<mrvn>
shouldn't that look at every char once and copy every char once?
<noah>
mfp: well the nsplist stuff is all in my loading procedures. they seem to run comparably to my python implementation. the real problem starts in init_scores (line 207). here it gets to be about 1000 times slower than python for some reason
<mrvn>
(- the delimeter)
<mfp>
also, List.iter f (Str.input_list (open_in x)) can be replaced by Enum.iter f (IO.input_lines ch)
<mrvn>
#
<mrvn>
let date_list = (match (List.split_nth 39 trading_dates) with (a,b) -> a) in
<mrvn>
That doesn't sound too smart.
<mfp>
mrvn: IIRC it just find the delimiter, gets the RHS substring, loops
<noah>
mrvn: i'm not sure what you're talking about ("shouldn't that look at....")
<mrvn>
noah: you are splitting list into 2 parts and then throw one away.
<mrvn>
next line you split it again.
<noah>
mrvn: yep, i'm trying to take only the first 39 cells of the list, then only the last N cells of that second list
<noah>
mrvn: the context is that i am only using the first 39 cells for initing, but the specific init period depends on an input
<noah>
mrvn: e.g., i might want to take cells 5-39, or 19-39, etc.
<mrvn>
you can roll that into one recursive function.
<noah>
haha, yeah, it did seem pretty clunky, but i wasn't sure how to do it better
<mrvn>
I still don't see where all the time could go. There is no recursion or such.
<noah>
yeah, it is really mystifing me. i've been confused for past 2 or so days
<mrvn>
List.nth list 0 is List.hd
<mfp>
(noah: btw. no diff performance wise, but you can replace all those let _ = xxx in (* of type unit *) by xxx; which will also give you a warning if xxx isn't of type unit)
<mrvn>
list_min/max should use List.fold_left
<mrvn>
or let () = xxx in
<mfp>
I only do let () = xxx when using pa_monad
<mfp>
the ';' sequencing operator is just fine otherwise
<mrvn>
let x = 17 str in y; let z = 23 in ... has bad indentation.
<noah>
what is the diff between let _ = xxx in and let _ = xxx in?. and thanks for the ";" comment. i read i could do that, but then ran into the unit warning, and then figured out how to fix it, but didn't go back to change it
<noah>
let () = xx in and let _ = xxx in
<mfp>
the second matches anything
<mrvn>
noah: let () = xxx must have xxx return unit.
<mfp>
the former, only unit, so let () = 1 + 1 wouldn't type
<mrvn>
let _ = xxx in is equivalent to ignore (xxx);
<noah>
ok, so why not just use "let _ = xx in" for everythign always?
<mrvn>
#
<mrvn>
let min = list_min !top_tickers in
<mrvn>
#
<mrvn>
let min_index = match min with (a,b) -> a in
<mrvn>
#
<mrvn>
let min_ticker = match min with (a,b) -> b in
<mfp>
noah: you said that function was 1000x slower than the Python one?
<noah>
yeah, around that
<mrvn>
let (min_index, min_ticker) = list_min !top_tickers in
<mfp>
noah: because xxx; is shorter, and the warning is a good thing, it tells you when you're ignoring a non-unit value
<noah>
ok, makes sense. the ";" really does seem cleaner style
<mrvn>
noah: it is easy to forget an argument to a function for exmaple.
ztfw has quit [Read error: 104 (Connection reset by peer)]
<mrvn>
let _ = (+) 1 in is fine, (+) 1; tells you it is not.
<noah>
mrvn: ok, that makes a lot of sense. cuz you could just be assigning _ to a function
<mrvn>
noah: Maybe instead of lists you should use a set so you have min_elt and max_elt.
<mrvn>
for choose_stocks for example.
<mrvn>
noah: How long does this run?
<noah>
mrvn: well, i don't want only the minimum. i want the min N
<mfp>
noah: you can get them in O(N log N) time by removing the min_elt from the set and getting the new minimum recursively
<noah>
well, in python, after loading, it takes about 20 seconds or so. and here it seems to take a loooot longer. i kill it after like 8 minutes.
<noah>
this is O(size of set) isn't it?
<mfp>
"this"?
<noah>
the current implementation
<noah>
as opposed to O(NlogN)
<mrvn>
O(size^c) for some c
julm has quit [Read error: 110 (Connection timed out)]
<mfp>
c = 1
<mrvn>
I don't see how it could be O(c^size)
<mrvn>
mfp: nah, definetly not c=1 so far.
<mfp>
mrvn: are we talking about list_min on l75?
<noah>
no, i'm not iterating through size over and over. i'm iterating through size only one time. and on the way, i'm collecting the top 15 or whatever
<noah>
mfp: yeah, i think line 175 is what we're talking about
<mrvn>
mfp: I ment overall
julm has joined #ocaml
<noah>
min of (15 best) is constant time. so i'm just running that for the whole list - 15
<mfp>
ah well, that much is certain
<mfp>
if it were O(n), it'd certainly be faster than the Python one ;)
<noah>
haha, well, a fair point. but i don't see how it's not O(n)
<mrvn>
choose_stocks ist at least O(n) already
<mrvn>
#
<mrvn>
let _ = StrMap.iter choose_stocks !stock_score_map in
<mrvn>
that makes it O(n^2) at least
Ched has quit [Read error: 110 (Connection timed out)]
<mrvn>
noah: try to pull out constant expressions from functions. e.g. in choose_stocks the int_of_float (List.nth gen 0) is a constant. Calculate it before the function.
Ched has joined #ocaml
<noah>
mrvn: okay, that makes sense. but i think that line 189 is what gets us to O(N)
<mrvn>
noah: that takes it to O(n^2)
<noah>
because of the StrMap.find?
<mrvn>
because of List.length !top_tickers and list_min !top_tickers
<mfp>
it's rather unfortunate that Map.S doesn't doesn't expose min_elt & max_elt
<mrvn>
mfp: use set instead of map
<noah>
but set doesn't give me key value mappings, right?
<mfp>
the workaround is a set of tuples
<mfp>
with a comparison function that ignores the 2nd element of the tuple
<mfp>
and thus only compares the keys
<mfp>
(key * value tuples)
<noah>
mrvn: List.length is used on a different list. top_tickers is not the big set here, i.e. stock_score_amp. List.length runs in constant time for our purposes, i believe
<noah>
mfp: okay, i guess that makes sense. the advantage is just that then you have min_elt?
<mrvn>
Map should really have min_elt and max_elt.
<mfp>
yes, that'd allow you to pick the min/max N in N log N time
<mrvn>
and fold_left/fold_right
<mrvn>
You can use Map.fold to get the N min elements but not max.
<noah>
quick overall question -- is it okay to use lots of refs? i feel like i use more than i ought to. like i'm trying to do imperative style programming
<mrvn>
noah: better not to
<mfp>
in particular, refs + lists = something wrong ;-)
<mfp>
lists call for recursive functions in general
<mrvn>
noah: for example your list_min/max is totaly wrong. Use List.fold_left
<noah>
ok. i'd never seen anything like List.fold_left before, so i sort of ignored it, but i think i get what it does now
<mfp>
(or HOFs like fold_left/right)
<mfp>
noah: hmmm wasn't fold_left called reduced in Python? (before it was removed by Guido??)
<mfp>
*reduce
<mrvn>
noah: it lets you do something to every item in a list while carrying around some state, like the min element so far.
<mrvn>
noah: your state here would be (min_inxed, min_elt, curr_index)
<noah>
ah, ok, yeah i think i get how to use it. and i guess it actually is like reduce. but i never have used that stuff that much
<noah>
so i should consider using sets rather than maps, and also look for places where i use ref, and see if fold_left could be used instead
<mrvn>
Actually fold_left might not be optimal here. let rec loop min_idx min_elt cur_idx = ... might be better. No need to create and destroy tripple all the time.
<noah>
and that is what the folds implicitly do?
<mrvn>
noah: anything with ref and List.iter can probably written as List.fold*
<noah>
yeah, makes sense
<noah>
fold just takes the ref's state with it
<mrvn>
exactly.
<mrvn>
fun tup -> match tup with (t, p, a, c) ==> fun (t, p, a, c)
<noah>
thanks so much for taking a look at this stuff. i think ocaml has been harder to get set up than i expected, but the community has been even more helpful than for most languages, so it's kind of balanced out, haha
<mfp>
noah: in general, try to get rid of List.nth, List.remove, split_nth, assoc, findi... they're all O(n) and easily turn your program into O(n^c); there are better structures for those ops (arrays, sets, maps...)
<mrvn>
noah: line 104: You can write function (t, p, a, c) when p ?= pname -> ... | _ -> ()
<mrvn>
-?
<mrvn>
sam for the c = "0"
<noah>
mrvn: that is better than doing ifs?
<mrvn>
noah: less to type and more readbale imho
<noah>
yeah, agreed. i did some tests, because i thought maybe that "match tup" bit was slwoing things down, and i actually found that it was faster than fun (t, p, a, c) consistently
<noah>
i'm still a little confused about finding the min N elements of the set tho
<mrvn>
noah: take the min_elt, remove it, take min_elt, remove it, 15 times.
<noah>
i'm not really graet with algorithms, but kth order statistic is worst-case linear, right? and i'm getting 0th - 15th
<noah>
so that is O(15N) = O(N), no?
<noah>
er, 0th - 14th, or whatever
<noah>
i get how to do it with sets, but i don't see what it's not O(N) in this implementation
<noah>
*why it's not
<mrvn>
noah: A set is a balanced tree. insert/remove/find is O(log n).
<noah>
ahhhhhh, so it's O(logN)
<mrvn>
min_elt/max_elt is even O(1) I think.
<noah>
ok, if it's a heap
<noah>
but that doesn't take into account rebalaning and re-heapifying, right?
<mrvn>
nah, it either caches those 2 values or even has all items in a sorted linked list.
<mrvn>
noah: rebalancing is a constant cost or gets amortised.
<mrvn>
noah: e.g. AVL trees need at most 2 rotations for an insertion, each of them takes O(1).
<mrvn>
And O(log n + 1 + 1) == O(log n)
<noah>
ok, i see what you're saying there. but if the underlying implementation uses a sorted linked list, then it has to *sort* the list, right?
<noah>
and that is going to be nlogn?
<mrvn>
No. it can build a tree and additionally maintain links between all leafs.
<mrvn>
Each leaf can know its left and right neighbour.
<mrvn>
I don't think Ocamls Set does though.
<noah>
what does it do? even with the setup and stuff, does it still work out to be O(logN) to get smallest 15 do you think?
<mrvn>
O(15 log n) == O(log n)
<mrvn>
you have to use it all the way though. Not take a list, convert to set and take the 15 elements. That would be O(n log n)
<noah>
sure sure, but i mean, the setup to get to where you can to O(logN). like, i see your point that you can build a tree in the background. but how might OCaml's set do it without doing that?
<mrvn>
building the tree will be O(n log n)
<noah>
whereas building the list will be O(N), right? so you get O(N) to build the list, and O(N) to get min 15, so total O(N)
<mrvn>
A set will only help you if you pick the 15 min_elt multiple times from the set.
alexyk has quit []
<noah>
yeah, i understand the methodology, i think.
<noah>
i'm just wondering if building the tree makes it not worth it
<mrvn>
and it looks like you are doing this n times.
<mrvn>
so O(n^2) becomes O(n log n)
<mrvn>
noah: alternatively you can roll your min_list and max_list into one and find both at the same time.
kaustuv has quit [Remote closed the connection]
<mrvn>
Doesn't save you anything in O() notation but avoids loading the list into cache twice.
kaustuv has joined #ocaml
<noah>
mrvn: yeah, good point. the list_min isn't really a timesink tho, as top_tickers is very short, i think
<mrvn>
noah: look at all the data structures you have and what access/modifications you do on them and then look if there are better structures for that kind of usage pattern. That is usualy crucial. Every structure has different benefits.
<mrvn>
anyway, way past my bedtime now. n8
<mrvn>
(4 am now)
<noah>
ah, europe? thank you so much for all your help!
<travisbrady>
what would be an appropriate data structure to when common operations are random access, finding elements and shuffling? an older version of my code was written in Python and I used a list there
<travisbrady>
pardon me, "to use when", not "to when"
jeddhaberstro has joined #ocaml
<travisbrady>
i was thinking of using an array but using lists in my shuffle function and then wrapping that in Array.of_list
seafood has joined #ocaml
alexyk has joined #ocaml
alexyk has quit [Client Quit]
romildo has joined #ocaml
<romildo>
Hi.
<romildo>
Is there any facility in ocaml to print (or convert to string) a value of an arbitrary data type without hand writing a function for this purpose?
<flux>
and it's got its own xml and xml request language modules
<flux>
too bad it doesn't have a lot going on on the documentation front :)
<flux>
or, as I said, you can fake it :-) from xmlstream.ml .. lexer | ws+ -> stream lexbuf | "<stream:stream" -> ..
Jedai has quit [anthony.freenode.net irc.freenode.net]
Jedai has joined #ocaml
<julm>
flux: and what do you do when the stanza you receive is not complete in the chunk you get from the socket ?
<julm>
you wait for more and you reparse all from the start
<julm>
very dirty
<flux>
julm, uh, why?
<flux>
simply request the next block from the lexer
<flux>
if that is scary, you can run the lexer in its own thread
<julm>
I don't understand "request the next block from the lexer"
<flux>
when parsing files not everything is usually loaded into memory at once
<julm>
ok
<flux>
lexer has access to a buffer structure which has operations 'advance' or 'get character'
<flux>
and when the buffer finds out it doesn't have enough data to satisfy the request, it refills the buffers
<flux>
look at the Lexing -module
<julm>
ok like that it's ok
kaustuv has quit [Remote closed the connection]
kaustuv has joined #ocaml
lutter has joined #ocaml
<julm>
and also you need to handle Unicode at least in UTF-8, and to have a lexer able to handle it
alexyk has quit []
<flux>
I don't think that's a problem either
<julm>
and you need an event manager
<flux>
infact that uses ulex, a unicode-aware lexer
<flux>
event manager?
<julm>
well I call it like that
<julm>
the code that handle the different requests, follow the stanza threads, etc.
<julm>
handles*, follows*
<julm>
that is, if you write a client
alexyk has joined #ocaml
travisbrady has quit [Read error: 104 (Connection reset by peer)]
travisbrady has joined #ocaml
<julm>
for instance at the begining it would handle the registration process, then the roster retrieval, then the wait for a message or anything
<julm>
actually there are 3 main stanzas : message, presence and iq
<mrvn>
It's sad that basically none of the parsers are written to hanle asynchron operations. I.e. parse till you run out of data and then later resume when the socket spits out more.
<mrvn>
s/hanle/handle/
<flux>
mrvn, it would be simple to implement, though
<mrvn>
Simple to write things in CPS form but still a lot of work.
<flux>
it might be simpler than you think.. but yes, CPS
<julm>
Mike Jin's Jabbr is in CPS form
<flux>
or rather, less work than you think
<flux>
sticking CPS at the point of 'return value' almost makes it work already :)
<mrvn>
takes getting used to as well.
<mrvn>
flux: flux the hard part is returning a continuation in the middle of the parse process thatgets invoked again later with moredata from the socket.
<mrvn>
For that the parser needs to interact with your IO module.
<julm>
flux: do you plan to work on XMPP in OCAML?
komar__ has quit [No route to host]
Axioplase has quit ["leaving"]
<flux>
julm, well, I don't think I have - or should have.. - time for it..
<flux>
but perhaps I'll take a look
<flux>
mrvn, well, if at certain point of code you can either proceed or wait for more data, you can stick a CPS there, propably with the help of mutation
<flux>
and the CPS chain can stop there
<flux>
of course if none of your code is prepared for the case of block not providing sufficient data for progress, then you're stuck refactoring most of the branches..
<flux>
mrvn, but, if it's really that bad, you can always for for threads
hto has quit [Read error: 60 (Operation timed out)]
hto has joined #ocaml
<julm>
flux: if you ever get time for it, then I would be glad to help
willb has joined #ocaml
<flux>
I'll keep that on my mind
<mrvn>
flux: Idealy I want someone else to do the dirty work. :)
<flux>
well, I played around with the library, and my first problem (aside from guessing what the various fields and parameters are for) is exception "XMPP version is not equal to 1.0"
<flux>
ah, there's an existing client on the repository also
<flux>
sulci
<flux>
..I think.
komar__ has joined #ocaml
<flux>
apparently it's not completely up to date, it doesn't compile
<flux>
it looks like the xmpp-module isn't as up-to-date as the sulci-module is
ikaros has quit ["Leave the magic to Houdini"]
<flux>
ah, there's another branch, much more recent to boot!
<flux>
the another branch is called "trunk"...
<julm>
trunk as a version from 2008/12/15
<julm>
has*
<flux>
hm, the most recent log entry is from 2009-01?
<flux>
but I suppose it makes no practical difference
<flux>
the branch I was looking for was from 2007
<flux>
s/for/at/
<flux>
the bot (sulci) is not that a small project I see
<flux>
well, it was way simpler to pull the branch and compile like it was supposed to :-)
<flux>
it uses a nice trick for handling findlib for its associated modules, I think I might try that some time
<julm>
ah there is an Http_suck module xD
<julm>
Anastasia's Hooks module is the event manager I was talking about
<flux>
crap, some .mli have disappeared in the more recent version. and here I was hoping someone would've had an inspiration to write documentation :-)
thelema has joined #ocaml
<flux>
she apparently is part of the club where the symbol won't be bind twice: let a1 = List.remove_assoc "to" attrs in let a2 = List.remove_assoc "from" a1 in let a3 = Xml.filter_attrs (("from", to_) :: ("to", from) :: a2) in let a4 = match lang with ..
<flux>
while I an of the opinion that that kind of use is a prime candidate for symbol reuse
<mrvn>
I always reuse the symbol or pick a truely different name if the old one is still needed. Too much risk of confusion.
<mrvn>
np
<mrvn>
ups
alexyk has quit []
<flux>
from the looks of it (sulci) the xmpp module seems quite easy to use, atleast for this use case
<thelema>
let a = List.remove_assoc "to" attrs |> List.remove_assoc "from |> (fun x -> ("from", to_) :: ("to", from) :: x) |> Xml.filter_attrs
<thelema>
stream style programming.
* thelema
likes the idea of not binding temporary values
<olegfink>
there is a certain functional language where this style is rather common.
<thelema>
F#
<olegfink>
and also a whole family of languages where function composition and whole-list function applications are central
<olegfink>
well, a more canonical example would be haskell
<thelema>
composing functions too much takes away from understandability
<thelema>
but I do like the idea of threading a chunk of "state" through a series of transformations
<thelema>
not global state, a minimal subset of that.
<olegfink>
hm, I guess it's where you would like to draw a line
<olegfink>
from 'for(int i=0;i<N;i++) s+=a[i]' to 'List.fold (+) 0 a' to '+/'
<olegfink>
er, +/a
<mrvn>
and +\a would List.map?
<thelema>
I like the idea that sections of my program have definite boundaries on what they can affect. Functional separation.
<olegfink>
well, List.map would be +'a, +\a is scan: (1+)'1 2 3 -> 2 3 4, +\1 2 3 -> 1 3 6
<olegfink>
thelema: it's also a great way to write well-documented programs; I kind of miss the ability to define functions in arbitrary order in ocaml
<thelema>
arbitrary order
<olegfink>
not arbitrary, but the one that makes more sense for explanation purposes
<olegfink>
thelema: by the way, what about point-free notation for you example?
travisbrady has quit []
<kaustuv_>
I find the laziness in definitions in haskell to be one of its major faults, personally. I don't care about functions that use a datatype on page 1, especially if it has cutesy infix constructors, if the definition of the type is hidden on page 50.
<kaustuv_>
And I reserve a special rage for people who mix interleave function clauses
<kaustuv_>
s/mix//
kaustuv_ has quit ["ERC Version 5.3 (IRC client for Emacs)"]
_zack has quit ["Leaving."]
Israel has quit []
ikaros has joined #ocaml
komar_ has joined #ocaml
komar__ has quit [Read error: 113 (No route to host)]
alexyk has joined #ocaml
Israel has joined #ocaml
<flux>
kaustuv, people who do what?
Yoric[DT] has joined #ocaml
_zack has joined #ocaml
<flux>
hmm, I think I just managed to install the jabber server that doesn't work with sulci..
thelema has quit [Read error: 110 (Connection timed out)]
<Camarade_Tux>
=)
<flux>
fortunately(!) it was mentioned on the site
travisbrady has joined #ocaml
Amorphous has quit [Read error: 110 (Connection timed out)]
Amorphous has joined #ocaml
robocop has left #ocaml []
ThomasHC has joined #ocaml
dejj has joined #ocaml
sporkmonger has quit ["Poof!"]
alexyk has quit [Read error: 110 (Connection timed out)]
komar_ has quit [Read error: 104 (Connection reset by peer)]
komar_ has joined #ocaml
alexyk has joined #ocaml
hkBst has joined #ocaml
ThomasHC has quit [Remote closed the connection]
<flux>
ooh, I managed to create a connection in the toplevel
LeCamarade is now known as LeCamarade|Away
<flux>
but finding out how to sendi a message is too much effort for this night
<flux>
(and no, I didn't keep trying to do that all this time, I just returned back to it and it worked :))
alexyk has quit []
slash_ has joined #ocaml
smimou has joined #ocaml
BiDOrD has quit [Read error: 110 (Connection timed out)]
BiDOrD has joined #ocaml
prigaux has quit [Remote closed the connection]
noah has joined #ocaml
noah has quit [Client Quit]
Alpounet has quit [Remote closed the connection]
sporkmonger has joined #ocaml
prigaux has joined #ocaml
_zack has quit ["Leaving."]
Israel has quit []
bombshelter13_ has quit [Remote closed the connection]
itewsh has joined #ocaml
schme has joined #ocaml
wabash has joined #ocaml
<wabash>
Was looking at language shootout, and looks like ocaml is really really good.
<wabash>
Performance and elegance wise.
<wabash>
I asked this the other day, but I'm afraid I've gotten confused among reading about so many languages. Does Ocaml catch overflow/underflow? Does it have arbitrary size Integer types, and how does it handle big floating point numbers?
<mrvn>
no, yes.
<wabash>
mrvn: Ok, thank.s
<wabash>
mrvn: for floats..... how big does it go? Is it bigger than IEEE?
<mrvn>
haven't seen a module for arbitraryprecision floats yet.
<mrvn>
build one
<wabash>
mrvn; so floats are handled IEEE wise?
<mrvn>
normal floats are what the cpu does.
<wabash>
mrvn: I see. Does it understand NaN and Infinity values?
<mrvn>
wabash: does your cpu?
<wabash>
mrvn: Dunno, actually.......
<wabash>
Probably.
<wabash>
I'm guessing so, since C++ does it.
<Camarade_Tux>
wabash, just try 0./.0.;; in the toplevel :)
<wabash>
Yes, ok.
<wabash>
Is Ocaml frequently used for math stuff? Or is it more for logic?
julm has quit [Read error: 110 (Connection timed out)]
julm has joined #ocaml
<kig>
wabash: symbolic stuff is more its forte, but c-like math stuff doesn't run all too slow either (i guess within 2-4x if you're arithmetic-bound (4x if you're vectorizing your C?))
alexyk has joined #ocaml
<wabash>
kig: Thanks for responding. Well, If it's possible to do foreign method invocation, I'd use the GSL for vector and matrix stuff, but there's always non-vector math to do.
<wabash>
2-4x is not bad.
<wabash>
Ocaml lends itself to parallelization well?
<kig>
multicore stuff needs to be done with processes, so you have IPC overhead
<kig>
or um
<wabash>
Is it the actor model?
<wabash>
and also, by favoring parallel, I mean, is it purely functional stateless like Haskell?
<kig>
i think the ancient lib does a shared memory heap + multiprocess, i haven't tried it though
<schme>
best stick with fortran for the fast parallel math stuff ;)
<wabash>
ok, thanks kig. schme: would rather do GSL. trust more than fortran.
<kig>
oh, no DPH-like stuff. writing functional-style code in ocaml is easy enough if that's what you're asking?
<kig>
ocaml's not purely functional
<kig>
you can have an integer addition function that launches missiles
<schme>
That's a brilliant idea.
<wabash>
kig: Yes, kinda what I'm asking. I mean to say that I could write Ocaml with no side effects, and then it's easy to split work amongst processors.