Skip to content

Conversation

@iabdalkader
Copy link
Collaborator

No description provided.

@Bodobolero
Copy link

Thanks for reducing the dynamic memory usage of logging.

@iabdalkader

I think it is not necessary to guard for static strings like
https://github.com/arduino/arduino-iot-cloud-py/pull/73/files#diff-bacac9d865001a2293347f26dd66df12cdc58f0ad71654069e27afc44ce06c47L184

because static strings are in the read only memory segment anyway.

It only is necessary for f-strings which are concatenated dynamically based on parts like

https://github.com/arduino/arduino-iot-cloud-py/pull/73/files#diff-bacac9d865001a2293347f26dd66df12cdc58f0ad71654069e27afc44ce06c47R106

@iabdalkader
Copy link
Collaborator Author

iabdalkader commented Oct 23, 2023

because static strings are in the read only memory segment anyway.

I'm not entirely sure but I think that's only true if the module is frozen when running on MicroPython, but it's not normally frozen, it's loaded in memory and parsed, compiled etc.. but either way most of the strings are fstrings, at least the ones that get printed at every step, so the overhead is minimal.

Note in some cases a check is going to be done anyway, for example multiple debug statements, here an entire loop is skipped:

if log_enabled(logging.DEBUG):
    logging.debug("Pushing records to Arduino IoT cloud:")
    for record in self.senmlpack._data:
        logging.debug(f"  ==> record: {record.name} value: {str(record.value)[:48]}...")

@Bodobolero
Copy link

I'm not entirely sure but I think that's only true if the module is frozen when running on MicroPython, but it's not normally frozen

You are right - I was thinking of C/C++ Arduino code and string handling. I still need to remember myself that I am now using python.

@iabdalkader
Copy link
Collaborator Author

You are right - I was thinking of C/C++ Arduino code and string handling. I still need to remember myself that I am now using python.

For non-fstrings it's probably passed by a reference (pointer) to the string, it's maybe worth asking about, but since those are just a few lines that get executed once per connection, I will remove the check for them.

@iabdalkader
Copy link
Collaborator Author

@Bodobolero They do seem to consume memory:

import gc
import logging

logging.basicConfig(
    datefmt="%H:%M:%S",
    format="%(asctime)s.%(msecs)03d %(message)s",
    level=logging.INFO,
)

gc.collect()
logging.info("RTC time set from NTP.")
logging.info("RTC time set from NTP.")
logging.info("RTC time set from NTP.")
logging.info("RTC time set from NTP.")
mem = gc.mem_free()
gc.collect()
print(gc.mem_free() - mem)

Prints 1840 and it grows if you add more statements.

@iabdalkader
Copy link
Collaborator Author

No actually they don't if log level is say ERROR which I should have used, they don't consume any extra memory. So I will remove the check before static strings.

@iabdalkader iabdalkader force-pushed the logging_memory branch 2 times, most recently from fcfd0ff to a4afb86 Compare October 23, 2023 10:11
@iabdalkader iabdalkader merged commit cd59e69 into main Oct 23, 2023
@iabdalkader
Copy link
Collaborator Author

Updated an merged.

@iabdalkader iabdalkader deleted the logging_memory branch October 23, 2023 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants