From ad22010bf9ed13cc0f63332a7023932ec53e9182 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Wed, 17 Aug 2022 16:19:22 -0400 Subject: [PATCH 1/3] clarify common confusion about allocations --- doc/src/manual/performance-tips.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 5a4e2d3c32e5a..04967236a5f37 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -90,7 +90,9 @@ On the first call (`@time sum_global()`) the function gets compiled. (If you've in this session, it will also compile functions needed for timing.) You should not take the results of this run seriously. For the second run, note that in addition to reporting the time, it also indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in -a vector of 64-bit floats so there should be no need to allocate memory (at least not on the heap which is what `@time` reports). +a vector of 64-bit floats so there should be no need to allocate (heap) memory. + +We should clarify that what `@time` reports is specifically *heap* allocations, which are typically needed for either mutable objects or for creating/growing variable-sized containers (such as `Array` or `Dict`, strings, or “type-unstable” objects whose type is only known at runtime). Allocating (or deallocating) such blocks of memory requires an expensive system call (like `malloc` in C), and they must be tracked for garbage collection. In contrast, immutable values like numbers (except bignums), tuples, and immutable `struct`s can be stored much more cheaply, e.g. in stack or CPU-register memory, with no system call, so one doesn’t typically worry about the performance cost of “allocating” them. Unexpected memory allocation is almost always a sign of some problem with your code, usually a problem with type-stability or creating many small temporary arrays. @@ -98,8 +100,8 @@ Consequently, in addition to the allocation itself, it's very likely that the code generated for your function is far from optimal. Take such indications seriously and follow the advice below. -If we instead pass `x` as an argument to the function it no longer allocates memory -(the allocation reported below is due to running the `@time` macro in global scope) +In this particular case, the memory allocation is due to the usage of a type-unstable global variable `x`, so if we instead pass `x` as an argument to the function it no longer allocates memory +(the remaining allocation reported below is due to running the `@time` macro in global scope) and is significantly faster after the first call: ```jldoctest sumarg; setup = :(using Random; Random.seed!(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" From 72d424acfaab26258070e7b51cc330fe8c741bde Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 1 Sep 2022 10:42:46 -0400 Subject: [PATCH 2/3] qualify remark about system call with "may", add line breaks, use straight quotes --- doc/src/manual/performance-tips.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 04967236a5f37..93220ea6345f3 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -92,7 +92,11 @@ of this run seriously. For the second run, note that in addition to reporting th indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in a vector of 64-bit floats so there should be no need to allocate (heap) memory. -We should clarify that what `@time` reports is specifically *heap* allocations, which are typically needed for either mutable objects or for creating/growing variable-sized containers (such as `Array` or `Dict`, strings, or “type-unstable” objects whose type is only known at runtime). Allocating (or deallocating) such blocks of memory requires an expensive system call (like `malloc` in C), and they must be tracked for garbage collection. In contrast, immutable values like numbers (except bignums), tuples, and immutable `struct`s can be stored much more cheaply, e.g. in stack or CPU-register memory, with no system call, so one doesn’t typically worry about the performance cost of “allocating” them. +We should clarify that what `@time` reports is specifically *heap* allocations, which are typically needed for either mutable objects or for creating/growing +variable-sized containers (such as `Array` or `Dict`, strings, or "type-unstable" objects whose type is only known at runtime). Allocating (or deallocating) such +blocks of memory may require an expensive system call (e.g. via `malloc` in C), and they must be tracked for garbage collection. In contrast, immutable values like +numbers (except bignums), tuples, and immutable `struct`s can be stored much more cheaply, e.g. in stack or CPU-register memory, so one doesn’t typically worry about +the performance cost of "allocating" them. Unexpected memory allocation is almost always a sign of some problem with your code, usually a problem with type-stability or creating many small temporary arrays. From 6dbf4d59e49a9c8586fa1b17b3fa66bd6cb67534 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 1 Sep 2022 10:47:15 -0400 Subject: [PATCH 3/3] shorter line breaks (grr, manual linewrapping) --- doc/src/manual/performance-tips.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 93220ea6345f3..f2ad9884e9548 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -92,11 +92,12 @@ of this run seriously. For the second run, note that in addition to reporting th indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in a vector of 64-bit floats so there should be no need to allocate (heap) memory. -We should clarify that what `@time` reports is specifically *heap* allocations, which are typically needed for either mutable objects or for creating/growing -variable-sized containers (such as `Array` or `Dict`, strings, or "type-unstable" objects whose type is only known at runtime). Allocating (or deallocating) such -blocks of memory may require an expensive system call (e.g. via `malloc` in C), and they must be tracked for garbage collection. In contrast, immutable values like -numbers (except bignums), tuples, and immutable `struct`s can be stored much more cheaply, e.g. in stack or CPU-register memory, so one doesn’t typically worry about -the performance cost of "allocating" them. +We should clarify that what `@time` reports is specifically *heap* allocations, which are typically needed for either +mutable objects or for creating/growing variable-sized containers (such as `Array` or `Dict`, strings, or "type-unstable" +objects whose type is only known at runtime). Allocating (or deallocating) such blocks of memory may require an expensive +system call (e.g. via `malloc` in C), and they must be tracked for garbage collection. In contrast, immutable values like +numbers (except bignums), tuples, and immutable `struct`s can be stored much more cheaply, e.g. in stack or CPU-register +memory, so one doesn’t typically worry about the performance cost of "allocating" them. Unexpected memory allocation is almost always a sign of some problem with your code, usually a problem with type-stability or creating many small temporary arrays.