Why OS.execute is so slow?

Godot Version

4.1.1

Question

I use OS.Execute to run python code, but it takes a very long time to execute the code (about 15s always, whatever the code is). This is how my code looks like on Godot:

func post_message():
	while thread.is_alive():
		if send_message:
			send_message = false
			var time_start = Time.get_time_dict_from_system()
			print("start: %02d:%02d:%02d" % [time_start.hour, time_start.minute, time_start.second])
			var message = 'Hello there! How are you?'
			var output = []
			var process = OS.execute(interpreter_path, [message], output)
			var time_finish = Time.get_time_dict_from_system()
			print("finish: %02d:%02d:%02d" % [time_finish.hour, time_finish.minute, time_finish.second])
			print("output: " + str(output))

At the same time, if I run the code on my computer or run it through OS.create_process, it executes quickly (definitely not 15s), how to fix this. Is it possible to get the output to the console in the OS.create_process function? Or is there another solution? Please help. :pray:

I have some suggestions

You should try the execution command inside a native shell.

Windows: cmd or powershell
Mac/Linux: bash or sh

So instead of python script.py args it becomes <shell> -c "python script.py args"

Another option is to debug a little more to understand the delay. You can have the execution command funnel stdrerr into the output or have it open a console window.

1 Like

At first I thought it was working because it gave me an error quickly (in 2-3s), but then I fixed it and still the code runs for 12-15s.

I tried both cmd and powershell, but the results are the same in terms of speed, still not fast enough

the code runs for 12-15s.

Maybe it’s because in the python code I’m getting data from the network (i.e. I’m waiting for a response to come to me). For some reason it takes quite a while for Godot to get a response (+10s from running locally)

That said, if I run simple code that doesn’t involve the network, the code executes instantly (or almost instantly, but still quite fast).

I found a more or less normal solution.
I use OS.create_process, the rest of the code as well, but I save the python script output to a file, and then in the Godot code I check to see if there is any new data (one line is stored in the file, then I save to a variable output and clear the file):

func post_message():
	var time_start = Time.get_time_dict_from_system()
	print("start: %02d:%02d:%02d" % [time_start.hour, time_start.minute, time_start.second])
	var message = "Hello there! How are you?"
	var file_name = "bot_answer.txt"
	var process = OS.create_process(interpreter_path, [script_path, message, file_name])
	var bot_answer = Global.read_data("user://bot_answer.txt")
	while bot_answer.is_empty():
		await get_tree().create_timer(1.0).timeout
		bot_answer = Global.read_data("user://bot_answer.txt")
	Global.clear_data("user://bot_answer.txt")
	var time_finish = Time.get_time_dict_from_system()
	print("finish: %02d:%02d:%02d" % [time_finish.hour, time_finish.minute, time_finish.second])
	print("output: " + str(bot_answer))

In the end I got a satisfactory result (4-5s code execution as it should be, i.e. speed like a local run, perfect).

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.