BurntSushi / advent-of-code

Rust solutions to AoC 2018

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Day12: Slowlyness from usage of string?

fabienjuif opened this issue · comments

Hi @BurntSushi

I see you use enums, structs, etc in day12.
I used strings: https://github.com/fabienjuif/advent-of-code-2018/blob/master/day12/src/main.rs

Do you think this is because of string usage that my code is 10x slower than yours?
Or do you think this is because of this? https://github.com/fabienjuif/advent-of-code-2018/blob/master/day12/src/main.rs#L24

(creating a new string each loop, I try other way to construct that string, so I guess this is not HOW this new string is built, but maybe just that the fact I build a new string each loop?)

I don't ask you to debug my code!
I just want to know if you can quickly see an issue there, if you have time!

Thank a lot, once again :)

I think this is not because of copy, don't bother looking at all of this I think this is a bad idea to use a string as a storage 😓

This modification changes nothing:
https://github.com/fabienjuif/advent-of-code-2018/pull/6/files#diff-493c6a98633aede7c59a840f35cb4a30R27

edit: I think this is because of string mutation (https://github.com/fabienjuif/advent-of-code-2018/pull/6/files#diff-493c6a98633aede7c59a840f35cb4a30R37)

@fabienjuif I don't think it's anything as specific as "string mutation." If you look at my loop in step, I believe it runs a fixed number of iterations once it hits convergence on the pattern. That is, once it reaches that point, the number of pots remains the same from one iteration to the next. I chose a sparse representation, so the underlying storage scales proportionally to the number of pots with plants. I believe your representation is dense, which means storage does not scale proportionally to the number of pots with plants, but rather, to the total number of pots. The total number of pots grows without bound for this specific input I think. e.g., Try this right before your patterns.iter() call:

        println!("iters: {:?}", patterns.len() * (pots.len() - 5));

If you do something similar in my code, I think you'll see the difference. :-)

Note also that calls like pots.insert_str(0, ".") take linear time in the size of pots (but pots.push(".") is amortized constant time).

  1. I don't think I can use pots.push(".") because I want to add the point BEFORE (at start).
  2. You are right: iters: 694484

This is so interesting to dig all of that.
This is a long time I didn't write low level code :) (I am used to JS), and this is refreshing digging that with your support!

I feel really dumb somehow sometimes.

edit:
I re-read your code and you are right, I think your magic happens here: https://github.com/BurntSushi/advent-of-code/blob/master/aoc12/src/main.rs#L73..L74

Thank you!