diff --git a/.jules/bolt.md b/.jules/bolt.md index 9e4d903..c82a56b 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -8,3 +8,7 @@ ## 2024-05-11 - [XML Lookup Optimization] **Learning:** Repeatedly calling `pugi::xml_node::find_child_by_attribute` to look up prayer times by `dayofyear` is an O(N) linear search bottleneck that slows down `zaman` class instantiations. **Action:** Replaced it with an O(1) array lookup. Since `dayofyear` acts as a sequential 0-based index (0-365), we can cache the `const char*` text of each `prayertimes` node into a static `cached_nodes[400]` array using a magic static block. This reduced instantiation time nearly by half. + +## 2026-05-16 - [Optimize String Formatting via Stack Buffer] +**Learning:** In heavily called string formatting functions like `td_to_vakt`, multiple `std::to_string` allocations and string concatenations (`+`) cause severe memory allocation bottlenecks. +**Action:** Using a manual, fixed-size stack character buffer (e.g., `char buf[6]`) and direct ASCII arithmetic (`'0' + value`) avoids temporary object creation and yields a significant performance improvement. diff --git a/run_tests b/run_tests deleted file mode 100755 index 6d4062d..0000000 Binary files a/run_tests and /dev/null differ diff --git a/src/src-class/Zaman.cpp b/src/src-class/Zaman.cpp index d65d370..dd1bab8 100644 --- a/src/src-class/Zaman.cpp +++ b/src/src-class/Zaman.cpp @@ -70,7 +70,25 @@ unsigned int zaman::vakt_to_td(const std::string& vakt) std::string zaman::td_to_vakt(unsigned int td) { - return std::to_string(int(td / 60) % 12) + ":" + std::to_string(int(td % 60)); + // ⚡ Bolt Optimizasyonu: std::to_string ve std::string birleştirme tahsisatlarını manuel karakter arabelleği ile engelle + int h = int(td / 60) % 12; + int m = int(td % 60); + char buf[6]; + int i = 0; + if (h >= 10) { + buf[i++] = '0' + (h / 10); + buf[i++] = '0' + (h % 10); + } else { + buf[i++] = '0' + h; + } + buf[i++] = ':'; + if (m >= 10) { + buf[i++] = '0' + (m / 10); + buf[i++] = '0' + (m % 10); + } else { + buf[i++] = '0' + m; + } + return std::string(buf, i); } void zaman::vkt_h_v_d() @@ -89,36 +107,19 @@ void zaman::vkt_h_v_d() char buffer[5]; - static const pugi::xml_node* cached_nodes = []() { - static pugi::xml_document doc; - if (!doc.load_file("include/XML/Vakitler.xml") && !doc.load_file("vakitler.xml")) { - throw std::runtime_error("XML load failed"); - } - pugi::xml_node node = doc.child("cityinfo"); - if (!node) { - throw std::runtime_error("Missing cityinfo node"); - } - - // ⚡ Bolt Optimizasyonu: XML düğümlerini 'dayofyear' özniteliğine göre önbelleğe alarak O(1) erişim sağla (O(N) doğrusal arama yerine) - // Her nesne örneği oluşturulduğunda O(N) doğrusal arama darboğazını ortadan kaldırır - static pugi::xml_node nodes[400]; - for (pugi::xml_node pt = node.child("prayertimes"); pt; pt = pt.next_sibling("prayertimes")) { + // ⚡ Bolt Optimizasyonu: XML düğümlerini 'dayofyear' özniteliğine göre önbelleğe alarak O(1) erişim sağla (O(N) doğrusal arama yerine) + // Her nesne örneği oluşturulduğunda O(N) doğrusal arama darboğazını ortadan kaldırır + static const char** cached_nodes_ptr = []() { + static const char* nodes[400] = {nullptr}; + for (pugi::xml_node pt = zaman::sehir.child("prayertimes"); pt; pt = pt.next_sibling("prayertimes")) { int day = pt.attribute("dayofyear").as_int(-1); if (day >= 0 && day < 400) { - nodes[day] = pt; + nodes[day] = pt.text().get(); } } return nodes; }(); - - static const char* cached_nodes[400] = {nullptr}; - static bool cached_nodes_init = []() { - for (pugi::xml_node pt = cached_sehir.child("prayertimes"); pt; pt = pt.next_sibling("prayertimes")) { - int day = std::atoi(pt.attribute("dayofyear").value()); - if (day >= 0 && day < 400) cached_nodes[day] = pt.text().get(); - } - return true; - }(); + const char* const* cached_nodes = cached_nodes_ptr; zaman::xml_bu_gun = (zaman::h_rakam_gun_senenin >= 0 && zaman::h_rakam_gun_senenin < 400 && cached_nodes[zaman::h_rakam_gun_senenin]) ? cached_nodes[zaman::h_rakam_gun_senenin] : "";