Forum Discussion

Laura_Dannisoe's avatar
Laura_Dannisoe
Frequent Visitor
4 years ago

List.Generate performance

Hello community! 

 

I have a function which calls an API and then loops until all data are retrieved. Therefore, I am using List.Generate, however I am experiencing it to be extremely slow. The number of rows i approx 300.000 and it can take more than 10 minutes to retreive!

 

I have come across the List.Buffer or Table.Buffer which apperarently should enhance the performance, but I don't know where to include it in my query. 

 

Can anyone help? 🙂

ImkeF maybe?

 

Query:

 

let
  Kilde = (EndPoint as text, optional Changedate as text, optional PositionOfResultRecordField)=>
let
    //EndPoint = "GetCustomersByLastChange",
    //PositionOfResultRecordField = 1,
    changedate = if Changedate = null then "" else Changedate,
    positionOfResultRecordField = if PositionOfResultRecordField is null then 1 else PositionOfResultRecordField,
    firstwebcall = SinglePageMB(EndPoint, changedate),
    StartRecord = firstwebcall[results]{0},
    Pagestoskip_ = List.Count(Record.Field(StartRecord,Record.FieldNames(StartRecord){positionOfResultRecordField})),
    NumberOfPages = Number.RoundUp(StartRecord[entriesleft]/Pagestoskip_),
    listGenerate = List.Generate(
        () => [result=StartRecord, resumekey=StartRecord[resumekey],pagestoskip=0,counter = 0],
        each [counter] <= NumberOfPages,
        //each [counter] < 3,
        each [
            result = Resumekey_function(EndPoint,[resumekey], changedate){0},
            counter=[counter]+1,
 //           pagestoskip = [pagestoskip]+Pagestoskip_,
            resumekey = try result[resumekey] otherwise null
        ]
    ),
    #"Konverteret til tabel" = Table.FromList(listGenerate, Splitter.SplitByNothing(), nullnull, ExtraValues.Error)
in
    #"Konverteret til tabel"
in
  Kilde

 

7 Replies

    • Laura_Dannisoe's avatar
      Laura_Dannisoe
      Frequent Visitor

      Hi 

       

      I have tried to watch the alternative in the video, but I am not quite sure how to implement that in my solution. Yes I am increasing the number of records. The limit is different for each endpoint in the API. 

       

      I thought that Buffer could decrease the performance time as it takes around 1,5 hours to refresh the report... 

      • ImkeF's avatar
        ImkeF
        Community Champion

        Hi Laura_Dannisoe ,
        a buffer is useful to stop re-evaluating tables or lists that will be referenced multiple times in iterators (like List.Generate, -.Accumulate, -.Transform or Table.AddColumn).
        But in your iterator here (List.Generate), there is no direct list or table input (just records or scalars). Therefore you cannot use it here.

        Does the function you're calling ("Resumekey_function") reference a table or a list? Then you might want to buffer that in there.

        There are other things to watch out for when optimizing performance: Speed/Performance aspects – The BIccountant maybe you find a hint in there.

         

    • Laura_Dannisoe's avatar
      Laura_Dannisoe
      Frequent Visitor

      Also the approach is using GET to my understanding right? Would prefer POST.