4 ms·
The functional style is nice and all, but once you’ve reaped the low hanging fruits some problems are very hard or cumbersome to tackle in a stateless fashion.
by stephc_int13 3y ago
The functional style is nice and all, but once you’ve reaped the low hanging fruits some problems are very hard or cumbersome to tackle in a stateless fashion.
I think this is bad advice, the lead to multiple dead ends. Especially in the fields I know, video games and embedded software, state and mutation are everywhere.
Embrace the state, parallelise your code instead of making it concurrent. Easier, almost always faster and more robust.
- cogman10 3y agoThis could very much be that different applications have different strategies that are applicable. For games and embedded systems, memory and CPU cycles are at a premium. My strat works best in languages with a GC where memory is abundant and cheap to allocate and there's not strict CPU time requirements. For the field I'm familiar with, microservices and backends, this works really well and mutation can generally be controlled (usually the only permanent state is the database). I agree shared state is probably faster, I'm not sure I agree with it being robust. Parallel code with shared state can be deceptively tricky to get right, especially when trying to hold multiple locks at the same time (which you have to do if you want to be fast). Nobody likes debugging why an app suddenly freezes for no apparent reason (deadlock).
- stephc_int13 3y agoNo, I am talking about lockless design. Split/join style. It is almost like a single threaded code, except that all heavy work is done as fast as possible in parallel, the single threaded part is almost free in practice, less than 1ms in total per frame, often 10 times less.
- cogman10 3y agoSplit/join is also what I was talking about but storing the values in immutable temporary heap locations rather than in a common lockless queue. If you have the memory and allocation speed, that can be much faster than a lockless queue (especially if that queue is under high contention). However, for a game and embedded system I'd imagine the impact on heap fragmentation would be a pretty significant reason not to do this. For a GCed language, those heap allocations are fairly cheap, quiet a bit cheaper than what you pay for in a managed memory language (In GCed languages, the majority of memory allocations are 1 or 2 conditional checks with a pointer bump. It's very nearly the same speed as stack allocation). When I was talking about mutable state (and my example is perhaps bad), I'm more talking about system or process wide mutable state.
- nine_k 3y agoDo mutable things inside your function. Have an immutable public interface. Also, split state so that it's not shared mutably among threads, and share immutable views when you need other threads to see it. There are more ways to not expose mutation.