byte-physics / igortest

Igor Pro Universal Testing Framework
https://docs.byte-physics.de/igor-unit-testing-framework/
BSD 3-Clause "New" or "Revised" License
7 stars 2 forks source link

JUNIT output is too slow #451

Open t-b opened 1 year ago

t-b commented 1 year ago

IP9.03 r40067

Code:

#include <FunctionProfiling>
#include "igortest"

Function Test()

    variable i

    for(i = 0; i < 10e2; i += 1)
        print "a"
    endfor
End

Function runme_ignore()

    runtest("Procedure")

    beginFunctionProfiling(testtime = 10)
    IUTF_JUnit#JU_WriteOutput()
    EndFunctionProfiling()
End

Profiling output:

Total time: 0.0231407, Time in Function code: 0.0231254 (99.9%)
Top function percentages:
Function igortest-junit.ipf JU_TrimSOUT: 76%
Function igortest-utils-xml.ipf WriteXML: 20%

Annotated Top Functions:

*******************************************************************************************
Function: igortest-junit.ipf igortest-junit.ipf#JU_TrimSOUT; Percent total 76%
*******************************************************************************************
[00]*           |static Function/S JU_TrimSOUT(input, [listSepStr])
[00]            |   string input
[00]            |   string listSepStr
[00]            |
[00]            |   variable i, numItems
[00]            |   string output = ""
[00]            |
[00]            |   if(ParamIsDefault(listSepStr))
[00]            |       listSepStr = "\r"
[00]            |   endif
[00]            |
[00]*           |   numItems = ItemsInList(input, listSepStr)
[00]*           |   for(i = 0; i < numItems; i += 1)
[75]********    |       output += TrimString(StringFromList(i, input, listSepStr))
[00]*           |       output += listSepStr
[00]*           |   endfor
[00]            |
[00]            |   return output
[00]            |End

*******************************************************************************************
Function: igortest-utils-xml.ipf igortest-utils-xml.ipf#WriteXML; Percent total 20%
*******************************************************************************************
[00]*           |static Function WriteXML(prefix, content, [outDir])
[00]            |   string prefix, content
[00]            |   string outDir
[00]            |
[00]            |   string fileName, msg
[00]            |   variable fnum
[00]            |
[00]            |   if(ParamIsDefault(outDir) || IUTF_Utils#IsEmpty(outDir))
[00]            |       fileName = IUTF_Utils_Paths#AtHome(prefix + GetBaseFilename() + ".xml", unusedName = 1)
[00]            |   else
[00]            |       fileName = outDir + prefix + GetBaseFilename() + ".xml"
[00]            |       fileName = IUTF_Utils_Paths#getUnusedFileName(fileName)
[00]            |       if(IUTF_Utils#IsEmpty(fileName))
[00]            |           sprintf msg, "Cannot determine unused file for %s at %s", fileName, outDir
[00]            |           IUTF_Reporting#ReportErrorAndAbort(msg)
[00]            |       endif
[00]            |   endif
[00]            |
[02]*           |   Open/Z fnum as fileName
[00]*           |   if(!V_flag)
[01]*           |       FBinWrite fnum, content
[17]**          |       Close fnum
[00]            |   else
[00]            |       sprintf msg, "Error: Could not create XML output file at %s", fileName
[00]            |       IUTF_Reporting#IUTF_PrintStatusMessage(msg)
[00]            |   endif
[00]            |End

Trimming the string should not be that slow. With > IP7 one can use multithread statements with text waves, maybe that is faster.

Garados007 commented 1 year ago

I think this part

numItems = ItemsInList(input, listSepStr)
for(i = 0; i < numItems; i += 1)
    output += TrimString(StringFromList(i, input, listSepStr))
    output += listSepStr
endfor

can be optimized by splitting the content in a text wave first and then iterating over it. The current approach has to many StringFromList calls which are really slow because it needs to scan the whole string repeatedly.