0

I am currently working on the development of a keyword that allows to separate the contents of a text file into 2 parts and create 2 new files containing each of these 2 parts. The file format is similar to a CSV file, except that the separator is a '|' (pipe). The file size is relatively large. We are talking here about 125 000 lines containing 10+ columns. I tried to write the keyword directly in Robot Framework as follows:

Split Files
    [Arguments]    ${filePath}    ${nbOfColumns}    ${separator}=|    
    OperatingSystem.File Should Exist    ${filePath}      msg=The file ${filePath} doesn't exist!
    ${fileContent} =    OperatingSystem.Get File    ${filePath}    encoding_errors=ignore
    @{lines} =    String.Split To Lines    ${fileContent}        
    : FOR    ${line}    IN    @{lines}
    \    ${rest}    ${last} =    CsvDiffLibrary.Split String From Right    ${line}    2
    \    OperatingSystem.Append To File    ${filePath}_old    ${rest}${\n}
    \    OperatingSystem.Append To File    ${filePath}_new    ${last}${\n}

The problem is that the execution of this keyword takes about 5 seconds for a file of 1000 lines ... and 10 seconds for a file of 2000 lines ... which means that it would take around 10 minutes for the entire file. It is not at all powerful and far from acceptable. (For information, for the treatment of the whole file, I forced the test to stop after 5 minutes of execution)

So I decided to write the keyword in Python, but also reusing the same Python libraries from Robot Framework:

def split_file(self, path, nb_of_columns):
    OperatingSystem().file_should_exist(path)
    file_content = OperatingSystem().get_file(path, encoding_errors='ignore')
    lines = String().split_to_lines(file_content)
    for line in lines:
        rest, last = self.split_string_from_right(line, nb_of_columns)
        OperatingSystem().append_to_file(path + "_old", rest + "\n")
        OperatingSystem().append_to_file(path + "_new", last + "\n")

You will notice that it is exactly the same thing, but in this way, the processing of 1000 lines is instantaneous and the whole file (123K lines) is processed in 20 seconds.

So my question is simple... why? Why so much difference between the keyword written in Robot Framework and the one written in Python? Because to my knowledge, Robot Framework is fully written in Python. There should not be so much overhead.

Thanks,

2

So my question is simple... why? Why so much difference between the keyword written in Robot Framework and the one written in Python? Because to my knowledge, Robot Framework is fully written in Python. There should not be so much overhead.

While there maybe shouldn't be that much overhead, there is indeed that much overhead. The overhead manifests itself in many ways:

  • In a robot framework keyword, every call to a keyword results in a line added to the log file. Plus, there is an additional line added for each iteration. When you call keyword functions from within a python-based keyword, none of those statements are logged. In your specific case, I'm calculating the robot-only solution will result in 500,000 additional lines of logging information (125,000 lines times four log statements per iteration)

  • There is the overhead of robot having to parse the code, which is small but not insignificant.

  • Robot has to do a lookup to map the keyword to a python function. Again, while that overhead is small, it's not insignificant. In your python version you're directly calling a function, which eliminates that overhead.

I suspect that the vast majority of the extra time is related to the tremendous amount of extra logging that is happening.


Note: you could probably make your python keyword an order of magnitude faster if you did everything in memory and then wrote the new files only once. Or, open the file once before the loop and directly write the data rather than calling the functino. Relatively speaking, calling OperatingSystem().append_to_file on every iteration is going to be very, very slow because it has to open, write, and close the file every time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.