Αρχιτεκτονική προσέγγιση και δομές δεδομένων

Η υλοποίηση ξεκίνησε με την ανάγκη αξιολόγησης αριθμητικών εκφράσεων μέσω δυαδικών δέντρων. Αντί για την παραδοσιακή προσέγγιση με ξεχωριστούς τύπους για κάθε πράξη (Add, Sub, Mul, Div), η αρχιτεκτονική απλοποιήθηκε σε μια γενική δομή Func Expr Expr, όπου ο evaluator δεν χρειάζεται να γνωρίζει τη φύση της πράξης, παρά μόνο πώς να την εφαρμόζει. Αυτή η αφαίρεση επέτρεψε την ενοποίηση μεταβλητών και συναρτήσεων στο ίδιο περιβάλλον (environment).

Διαχείριση μνήμης και custom allocators

Η χρήση της malloc για κάθε κόμβο (node) αποδείχθηκε αναποτελεσματική λόγω του overhead των metadata. Η λύση δόθηκε μέσω ενός chunk allocator, ο οποίος δεσμεύει μεγάλα τμήματα μνήμης (chunks) και τα συνδέει σε μια συνδεδεμένη λίστα. Αυτή η προσέγγιση απέφυγε τα προβλήματα του realloc, το οποίο θα καθιστούσε άκυρους τους δείκτες εντός του γράφου.

Η αναγκαιότητα του Garbage Collector

Κατά την αξιολόγηση αναδρομικών αλγορίθμων, όπως η ακολουθία Fibonacci, η συσσώρευση αχρησιμοποίητων κόμβων οδήγησε σε εξάντληση της μνήμης (OOM). Η υλοποίηση ενός mark-and-sweep garbage collector επέτρεψε την ανακύκλωση των κόμβων που δεν ήταν πλέον προσβάσιμοι από τη ρίζα του δέντρου, μειώνοντας δραστικά το memory footprint και επιτρέποντας την εκτέλεση πολύπλοκων υπολογισμών.

Συμπεράσματα και επόμενα βήματα

Το project εξελίχθηκε σε έναν πλήρη graph reduction engine. Παρά την επιτυχή διαχείριση της μνήμης, ο χρόνος εκτέλεσης παραμένει πρόκληση λόγω της εκθετικής φύσης των αλγορίθμων και της stop-the-world φύσης του garbage collector. Τα επόμενα στάδια περιλαμβάνουν την υλοποίηση Tail Call Optimization (TCO), ενός lexer/parser και τη βελτιστοποίηση της αξιολόγησης για την επίτευξη υψηλότερου throughput.