-
-
Notifications
You must be signed in to change notification settings - Fork 28
Description
The implementation for it and describe can space leak thunk and String.
Roughly speaking, both function takes the String for the name and convert it in a lazy way into a Text stored in the Specify or Describe node.
However this value is only evaluated when the name of the it or describe is required.
In a context where we dynamically build the test name (e.g. it ("testCase" <> foo)) it means that it maintains a thunk to the dynamic expression which can actually maintain alive a lot of objects.
In a context were i have multiple thousand tests with a dynamic name, I observed up to a GiB of retained data which should not be there and this had a negative impact on the test suite performance (e.g. GC was painfully walking all of these values). Using the following workaround removed these GiB (replacing them by more compact Text reference) and reduce the runtime of my test suite by up to 2x.
Workaround
One workaround for user are to force to WHNF the name before calling the it. In this context, it will still leak references to not compact String, but not to other object.
Another workaround is to fore the name to a compact data (e.g. Text) and then convert it to String. The GC will only have to track a thunk and the Text. For example:
describe "hello" $ do
let !name = "test" <> f x
it (unpack name) $ ...Solution
The Text value inside the Scecify or Describe node should be forced in the it or describe implementation.
I'll submit an MR soon, but I'm opening this issue for reference.