Anarchos has quit [Quit: Vision[]: i've been blurred!]
Tuplanolla has quit [Quit: Leaving.]
<discocaml>
<darrenldl> bit of a long shot: i remember a long time ago there was a small ocaml program that prints a "virtual keyboard" on the terminal, but with scrambled/randomised keys to somewhat protect against shoulder surfing. does that ring a bell to anyone?
leah2 has quit [Ping timeout: 260 seconds]
ygrek has quit [Remote host closed the connection]
reynir has quit [Ping timeout: 245 seconds]
reynir has joined #ocaml
semarie has joined #ocaml
semarie has quit [Client Quit]
leah2 has joined #ocaml
mbuf has joined #ocaml
semarie has joined #ocaml
chiselfuse has quit [Remote host closed the connection]
chiselfuse has joined #ocaml
pi3ce_ has quit [Read error: Connection reset by peer]
pi3ce has joined #ocaml
bartholin has joined #ocaml
leah2 has quit [Ping timeout: 252 seconds]
semarie has quit [Quit: quit]
leah2 has joined #ocaml
semarie has joined #ocaml
Haudegen has joined #ocaml
infinity0 has quit [Ping timeout: 248 seconds]
infinity0 has joined #ocaml
alexherbo2 has joined #ocaml
troydm has quit [Ping timeout: 260 seconds]
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #ocaml
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #ocaml
troydm has joined #ocaml
alexherbo2 has quit [Remote host closed the connection]
Anarchos has joined #ocaml
Anarchos has quit [Quit: Vision[]: i've been blurred!]
Anarchos has joined #ocaml
Anarchos has quit [Quit: Vision[]: i've been blurred!]
Anarchos has joined #ocaml
Anarchos has quit [Client Quit]
Anarchos has joined #ocaml
Anarchos has quit [Quit: Vision[]: i've been blurred!]
Haudegen has quit [Quit: Bin weg.]
Anarchos has joined #ocaml
Anarchos has quit [Client Quit]
mbuf has quit [Remote host closed the connection]
Anarchos has joined #ocaml
Anarchos has quit [Client Quit]
Haudegen has joined #ocaml
raskol has joined #ocaml
<discocaml>
<leostera> hi folks ๐ question as old as time but are there any studies/work/rationale written down somewhere to backup the โ50% the speed of Cโ claim we make?
gentauro has quit [Read error: Connection reset by peer]
gentauro has joined #ocaml
<discocaml>
<lukstafi> (Note it's relative to the style of code. And C++ can end up an order of magnitude slower with no optimizations compared to max optimizations, which I find funny.)
<discocaml>
<lukstafi> (Note it's relative to the style of code. And C++ can end up 2x slower -- don't remember precisely -- with no optimizations compared to max optimizations, which I find funny.)
<companion_cube>
Do we claim that? Embarrassing :/
<discocaml>
<dinosaure> in general, it's the opposite :3
Haudegen has quit [Quit: Bin weg.]
<discocaml>
<leostera> @companion_cube its one of those selling bullet-points that stuck with a lot of people
<companion_cube>
The opposite, as in, C++ faster than C? Yeah
Serpent7776 has joined #ocaml
<dh`>
the language is not a particularly good indicator of code performance
<discocaml>
<contificate> A lot of benchmark comparisons online are also comparing apples against oranges - or they're just a fully imperative algorithm where OCaml can't make any meaningful gains on a C implementation.
<dh`>
computers have gotten so fast that random bits of straight-line code are all faster than anyone can easily track, so speed problems that you can actually notice come from other factors
<discocaml>
<contificate> It's easy to write degenerate C that uses a lot of malloc/free in the wrong places and then destroy it with OCaml's generational GC. But, then, you can write an arena allocator in C as well and get back some losses.
<dh`>
usually, mishandling of bulk data
<dh`>
and usually the first-order performance problems will come from doing silly things
<dh`>
also even interpreted vs. compiled is no longer really a guide, lots of high-performance stuff gets written in python because the real work is happening in hand-tuned assembler or fortran
<dh`>
that the python interpreter is both super slow and unparallelizable doesn't matter
<companion_cube>
dh`: strong disagree, lots of languages have ceilings on the performance of idiomatic code
<companion_cube>
If your code fits in the special use case of some C or fortran library, sure, "python" is fast
<companion_cube>
We're so used to everything being slow that there's easy wins in software written in basically anything, that's also true
<companion_cube>
Anyway, if you do pay attention to performance, C will beat ocaml in most real cases, if you have the time and energy to make it Ruth
<companion_cube>
Right
<discocaml>
<yawaramin> wouldn't average C code beat average OCaml code in most real cases? assuming all other factors equal eg no obvious quadratic slowdpwns
<companion_cube>
Seems realistic to me
<companion_cube>
Except maybe for concurrency, as it's so hard in C?
leah2 has quit [Ping timeout: 246 seconds]
Haudegen has joined #ocaml
leah2 has joined #ocaml
<discocaml>
<contificate> companion cube is a secret C++ programmer
<discocaml>
<qrpnxz> companion_cube: C programmers have rather easy and efficient parallelism via OpenMP.
<companion_cube>
I did say concurrency though :)
<companion_cube>
Writing async code these days is a lot easier in ocaml
<discocaml>
<qrpnxz> That's true, but still seemed relevant to point out in the context of number crunching or those sort of workloads that you'd want C speed for.
<discocaml>
<qrpnxz> For aync, which often ends up being about IO specifically, there's stuff like libuv, but I can't say much about that since I've not experience with it.
<companion_cube>
I think we should ask good performance of everything, not just number crunching
<companion_cube>
Or at least be disappointed when things like slack are huge and slow and inefficient, even if it makes sense economically
Tuplanolla has joined #ocaml
<companion_cube>
Of course there's a lot of inefficiencies that are not just because of the language but also data representation (eg what comes to mind to me is opam, where the way the repo is represented means that every operation is slow)
<sleepydog>
performance in the absolute is kind of a boring metric unless you know you're working on a bottleneck
<sleepydog>
i'd be more interested in a comparison that penalizes code for being long or hard to read. for example, multiply the score by the time it takes an experienced programmer to understand it
<sleepydog>
usually in any given system there's only a handful of bottlenecks that you can only improve so much until you run up against a harder limit like IO.
<sleepydog>
for code outside of those bottlenecks, i'd rather it be easy to read and debug
noddy has quit [Quit: WeeChat 4.4.2]
noddy has joined #ocaml
<companion_cube>
It's what people say, but it's not really true? Eg what's the bottleneck in ocamlopt?
<companion_cube>
What's the bottleneck in nginx?
<companion_cube>
What's the bottleneck in dune?
<discocaml>
<contificate> We have a few auto-generated modules at work that take a long time to compile. Did -dtimings and it was actually typing that took the most time, rest of the compiler is pretty snappy.
<discocaml>
<donderdag> > Above all, optimization is avoided. We follow two rules in the matter of optimization:
<discocaml>
<donderdag> >
<discocaml>
<donderdag> > Rule 1. Don't do it.
<discocaml>
<donderdag> > Rule 2 (for experts only). Don't do it yetโthat is, not until you have a perfectly clear and unoptimized solution.
<discocaml>
<donderdag> >
<discocaml>
<donderdag> > Most programmers do too much optimization, and virtually all do it too
<discocaml>
<donderdag> > early. This book tries to act as an antidote. Of course, there are systems which
<discocaml>
<donderdag> > must be highly optimized if they are to be economically useful, and Chapter
<discocaml>
<donderdag> > 12 discusses some relevant techniques. But two points should always be
<discocaml>
<donderdag> > remembered: first, optimization makes a system less reliable and harder to maintain, and therefore more expensive to build and operate; second, because optimization obscures structure it is difficult to improve the efficiency of a system which is already partly optimized.
<companion_cube>
Please tell me that's not from "clean code"
<companion_cube>
But I follow a "don't pessimize" approach
<discocaml>
<donderdag> you mean, don't actively work to make something slower?
<discocaml>
<contificate> The real difficulty of retrofitting performance is leaky abstractions - the lack of `.mli` files over the years permitting people to just conflate ideas freely and without having to justify it really
<companion_cube>
I mean, think of performance as part of the design and the choices of data representation
<companion_cube>
You can't fix that later
<discocaml>
<contificate> You can make some efforts with fairly off-the-shelf techniques, but yeah it's tricky
<companion_cube>
And that's also where the multiple order of magnitude differences lie
<companion_cube>
(see again the opam case, where opam always loads a multi MB marshalled blob before any operation)
<discocaml>
<contificate> I've recently been shown to use `perf` etc. and it's great fun to just sample arbitrary programs and see the flame graphs
<companion_cube>
A choice made probably around 2011 and almost impossible to change now
<discocaml>
<contextfreebeer> you haven't been using perf?
<companion_cube>
perf is nice, I like Tracy and manual tracing too
<companion_cube>
flame graphs are just aggregates
<discocaml>
<contificate> Yeah, but it's a neat visualisation of some metric of cost
<discocaml>
<contificate> and, no, masterbuilder - not often
<discocaml>
<contificate> I mean I was surprised to learn that the industry standard is hacky Perl scripts written by the guy at Netflix
<discocaml>
<donderdag> > I mean, think of performance as part of the design and the choices of data representation
<discocaml>
<donderdag> that makes sense. i don't think we should ignore the question of which data structures to choose in order to best meet their usage patterns in a performant way
<companion_cube>
And it's a choice made early. Like security, you can't bake performance in later, it has to be in the original design
<discocaml>
<donderdag> right
<discocaml>
<contificate> You can still get an aggregation of marginal gains that are useful
<discocaml>
<contificate> Many things aren't a lost cause
<discocaml>
<contificate> The true suffering for me is approaching a module called "Foo" and thinking "alright, this is called Foo, it should only really be talking about Foo's concerns" and then, due to lack of interface restriction, there's random stuff all up inside it
<discocaml>
<contificate> turns refactoring efforts into a reverse engineering effort
<companion_cube>
Within a design you can still make good perf improvements, just not as big or easy
<discocaml>
<contextfreebeer> I think modular design so that you have the choice of improving performance is the best choice personally, rather than intentionally starting from a tangled design that is objectively more performant (since you can exploit the representation), if it really matters you should be able to open up the lid and make things more interdependent without too much issue, but the reverse is extremely difficult
<discocaml>
<contificate> I would like a tool to do this in dune automatically, actually - if you have a dune project and want to autogenerate a part of it, automatically factor out shared dependencies into an unwrapped library to break cycles
<discocaml>
<contextfreebeer> the industry standard is always some hacky nonsense, I am amazed that anything works at all
<discocaml>
<contificate> it's annoying though as it makes you wanna write an alternative to it for fun
<discocaml>
<contificate> and suddenly when you've been asked to get some perf flamegraphs for part of the program
<discocaml>
<contificate> you're sitting trying to parse the output of `perf script` or whatever it is
<discocaml>
<contificate> so you, too, can be the keeper of the fire
<companion_cube>
@contextfreebeer I agree, ousteroust (?) suggests deep modules for this reason
<discocaml>
<contificate> if we could get Intel PT on our stuff, we could use JS' magic trace
<companion_cube>
If you have a lot of code behind a simple interface you can change the design later
<discocaml>
<donderdag> 'modular design' is kind of a buzz word. it only makes sense if you already know how to do separation of concerns properly
<companion_cube>
@contificate just instrument your code with `trace` so you can see what's going on ๐
<discocaml>
<contificate> we already have our own version of that
<discocaml>
<contificate> assuming that's your otel lib
<discocaml>
<contificate> I feel like requiring `mli`s with doc comments is a good thing to strive for
<discocaml>
<contificate> so people can find it harder to slip things past you
<discocaml>
<contextfreebeer> what is your point exactly?
<discocaml>
<contificate> that said, can still just hide stuff in the `ml` and not expose it
<discocaml>
<donderdag> just that saying 'make it modular' is leaving a lot left unsaid. if you already know how to do good loose coupling, then you don't need to be told 'make it modular'. if you don't, then it doesn't communicate anything
<discocaml>
<contextfreebeer> I mean modular pretty literally given that we use ocaml, use the module system to your advantage
<companion_cube>
Oh not otel, I have a lighter weight abstraction that's pluggable
<companion_cube>
Including with otel
<discocaml>
<contificate> have you worked with OCaml 5 event ring buffer stuff
<discocaml>
<donderdag> ah, i see
<companion_cube>
No and I don't plan to
<discocaml>
<contificate> why not
<companion_cube>
It can apparently lose events
<discocaml>
<contificate> alright, I'll add an imgui UI and you'll use it
<companion_cube>
So if you get partial, possibly misleading data, meh
<discocaml>
<contextfreebeer> the alternative is "data driven design" done wrong i.e. everything is one big tangled pipeline, which is probably the maximum performance you can get out of modern hardware but at what cost, the code will be unintelligible and impossible to change
<companion_cube>
Stop with that bs plz
<discocaml>
<contificate> lmao
<discocaml>
<contextfreebeer> but my point is that you can go that extra mile if you really need to after the fact
<discocaml>
<contextfreebeer> but detangling is a nightmare
<companion_cube>
(cont I mean)
<discocaml>
<donderdag> that makes sense
<discocaml>
<contificate> I think an underrated design strategy in OCaml is to use functions as the universal interface
<discocaml>
<contificate> you sometimes see people go to lengths to return hash tables and all this nonsense
<discocaml>
<contificate> suddenly the signature talks about the resultant module of Hashtbl.Make etc.
<discocaml>
<contificate> I think ocamlgraph is fully designed this way: you ask for dominators and get a way to map a node to a node with a function
<companion_cube>
I tend to use a lot of opaque types
Stumpfenstiel has joined #ocaml
Stumpfenstiel has quit [Changing host]
Stumpfenstiel has joined #ocaml
<discocaml>
<qrpnxz> Speaking of tables, I have `module StringMap = Map.Make(String)` in a `Util` module. Didn't make sense for `BusinessLogic` or smth to own such a generic, generally useful module.
Everything has joined #ocaml
<companion_cube>
For sure
<companion_cube>
I name this `Common_` these days, as least for the ones always opened
raskol has quit [Ping timeout: 252 seconds]
<discocaml>
<deepspacejohn> on some projects that use maps a lot I've had a `map.ml` with `include Stdlib.Map module String = Stdlib.Map.Make(Stdlib.String)` and for int etc. Then I can just refer to `Map.String` everywhere.