How do you optimize software performance and minimize memory footprint when developing for resource-constrained embedded systems?