The March 2022 release of Power BI Desktop includes some new options for the Table.Buffer M function that can be set in a new second parameter. The options are of type BufferMode.Type; if you look at the built-in documentation for this type you’ll see the following:
The two allowed values are:
- BufferMode.Eager: The entire value is immediately buffered in memory before continuing
- BufferMode.Delayed: The type of the value is computed immediately but its contents are buffered until data is needed, at which point the entire value is immediately buffered
Anyone with previous experience of Table.Buffer will see that BufferMode.Eager is the existing behaviour, but what is BufferMode.Delayed for?
It turns out that it’s there to make development faster. Consider the following M query that loads data from a CSV file with seven columns and a million rows in, and then uses Table.Buffer to buffer that table into memory:
let
Source = Csv.Document(
File.Contents(
"C:\NumbersMoreColumns.csv"
),
[
Delimiter = ",",
Columns = 7,
Encoding = 65001,
QuoteStyle = QuoteStyle.None
]
),
#"Promoted Headers"
= Table.PromoteHeaders(
Source,
[PromoteAllScalars = true]
),
#"Changed Type"
= Table.TransformColumnTypes(
#"Promoted Headers",
{
{"A", Int64.Type},
{"B", Int64.Type},
{"C", Int64.Type},
{"D", Int64.Type},
{"E", Int64.Type},
{"F", Int64.Type},
{"G", Int64.Type}
}
),
BufferTable = Table.Buffer(
#"Changed Type"
)
in
BufferTable
When I refresh this query in Power BI Desktop on my PC I see the “Evaluating…” message for 20 seconds before the data starts to load:
If, however, I add the second parameter [BufferMode = BufferMode.Delayed] to Table.Buffer like so:
let
Source = Csv.Document(
File.Contents(
"C:\NumbersMoreColumns.csv"
),
[
Delimiter = ",",
Columns = 7,
Encoding = 65001,
QuoteStyle = QuoteStyle.None
]
),
#"Promoted Headers"
= Table.PromoteHeaders(
Source,
[PromoteAllScalars = true]
),
#"Changed Type"
= Table.TransformColumnTypes(
#"Promoted Headers",
{
{"A", Int64.Type},
{"B", Int64.Type},
{"C", Int64.Type},
{"D", Int64.Type},
{"E", Int64.Type},
{"F", Int64.Type},
{"G", Int64.Type}
}
),
BufferTable = Table.Buffer(
#"Changed Type",
[BufferMode = BufferMode.Delayed]
)
in
BufferTable
Then, when I run my refresh, the “Evaluating…” message only appears very briefly before the data starts to load:
It’s important to stress that after the “Evaluating…” phase the data load takes exactly the same amount of time – it’s only the “Evaluating…” phase that is faster. This can save you a lot of time as a developer, nonetheless. I have been told when these options are available in dataflows they will make validation (which occurs when you close Power Query Online after editing a dataflow) much faster too – in fact this developed to partially solve the dataflow validation problem.
[Thanks to Curt Hagenlocher for this information]