From 93495c3bfb9a36e0c9b523be4c898de9f7b59335 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Thu, 1 Dec 2022 11:35:14 -0800 Subject: [PATCH] Reduce unnecessary uses of std::list --- pyc_code.h | 6 ++--- pyc_module.cpp | 20 +++------------ pyc_module.h | 10 ++++---- pyc_numeric.cpp | 13 ++++++---- pyc_numeric.h | 6 ++--- pyc_sequence.cpp | 64 +++++++++++++++++++----------------------------- pyc_sequence.h | 13 +++++----- 7 files changed, 54 insertions(+), 78 deletions(-) diff --git a/pyc_code.h b/pyc_code.h index fa83119..bf0fa1d 100644 --- a/pyc_code.h +++ b/pyc_code.h @@ -3,10 +3,11 @@ #include "pyc_sequence.h" #include "pyc_string.h" +#include class PycCode : public PycObject { public: - typedef std::list > globals_t; + typedef std::set> globals_t; enum CodeFlags { CO_OPTIMIZED = 0x1, CO_NEWLOCALS = 0x2, @@ -76,8 +77,7 @@ public: void markGlobal(PycRef varname) { - m_globalsUsed.push_back(varname); - m_globalsUsed.unique(); + m_globalsUsed.emplace(std::move(varname)); } private: diff --git a/pyc_module.cpp b/pyc_module.cpp index 66745d4..aa739e5 100644 --- a/pyc_module.cpp +++ b/pyc_module.cpp @@ -235,26 +235,14 @@ void PycModule::loadFromMarshalledFile(const char* filename, int major, int mino PycRef PycModule::getIntern(int ref) const { - if (ref < 0) + if (ref < 0 || (size_t)ref >= m_interns.size()) throw std::out_of_range("Intern index out of range"); - - auto it = m_interns.cbegin(); - while (ref-- && it != m_interns.cend()) - ++it; - if (it == m_interns.cend()) - throw std::out_of_range("Intern index out of range"); - return *it; + return m_interns[(size_t)ref]; } PycRef PycModule::getRef(int ref) const { - if (ref < 0) + if (ref < 0 || (size_t)ref >= m_refs.size()) throw std::out_of_range("Ref index out of range"); - - auto it = m_refs.cbegin(); - while (ref-- && it != m_refs.cend()) - ++it; - if (it == m_refs.cend()) - throw std::out_of_range("Ref index out of range"); - return *it; + return m_refs[(size_t)ref]; } diff --git a/pyc_module.h b/pyc_module.h index d1c9ed5..4c75e9d 100644 --- a/pyc_module.h +++ b/pyc_module.h @@ -2,7 +2,7 @@ #define _PYC_MODULE_H #include "pyc_code.h" -#include +#include enum PycMagic { MAGIC_1_0 = 0x00999902, @@ -64,10 +64,10 @@ public: PycRef code() const { return m_code; } - void intern(PycRef str) { m_interns.push_back(str); } + void intern(PycRef str) { m_interns.emplace_back(std::move(str)); } PycRef getIntern(int ref) const; - void refObject(PycRef str) { m_refs.push_back(str); } + void refObject(PycRef obj) { m_refs.emplace_back(std::move(obj)); } PycRef getRef(int ref) const; static bool isSupportedVersion(int major, int minor); @@ -80,8 +80,8 @@ private: bool m_unicode; PycRef m_code; - std::list > m_interns; - std::list > m_refs; + std::vector> m_interns; + std::vector> m_refs; }; #endif diff --git a/pyc_numeric.cpp b/pyc_numeric.cpp index adc60a8..4f6d3c4 100644 --- a/pyc_numeric.cpp +++ b/pyc_numeric.cpp @@ -18,6 +18,7 @@ void PycInt::load(PycData* stream, PycModule*) void PycLong::load(PycData* stream, PycModule*) { if (type() == TYPE_INT64) { + m_value.reserve(4); int lo = stream->get32(); int hi = stream->get32(); m_value.push_back((lo ) & 0xFFFF); @@ -28,6 +29,7 @@ void PycLong::load(PycData* stream, PycModule*) } else { m_size = stream->get32(); int actualSize = m_size >= 0 ? m_size : -m_size; + m_value.reserve(actualSize); for (int i=0; iget16()); } @@ -41,9 +43,9 @@ bool PycLong::isEqual(PycRef obj) const PycRef longObj = obj.cast(); if (m_size != longObj->m_size) return false; - std::list::const_iterator it1 = m_value.begin(); - std::list::const_iterator it2 = longObj->m_value.begin(); - while (it1 != m_value.end()) { + auto it1 = m_value.cbegin(); + auto it2 = longObj->m_value.cbegin(); + while (it1 != m_value.cend()) { if (*it1 != *it2) return false; ++it1, ++it2; @@ -60,7 +62,8 @@ std::string PycLong::repr() const return "0x0L"; // Realign to 32 bits, since Python uses only 15 - std::list bits; + std::vector bits; + bits.reserve((m_value.size() + 1) / 2); int shift = 0, temp = 0; for (auto bit : m_value) { temp |= unsigned(bit & 0xFFFF) << shift; @@ -83,7 +86,7 @@ std::string PycLong::repr() const *aptr++ = '0'; *aptr++ = 'x'; - std::list::const_reverse_iterator iter = bits.rbegin(); + auto iter = bits.crbegin(); aptr += snprintf(aptr, 9, "%X", *iter++); while (iter != bits.rend()) aptr += snprintf(aptr, 9, "%08X", *iter++); diff --git a/pyc_numeric.h b/pyc_numeric.h index 6000f30..46ddb98 100644 --- a/pyc_numeric.h +++ b/pyc_numeric.h @@ -3,7 +3,7 @@ #include "pyc_object.h" #include "data.h" -#include +#include #include class PycInt : public PycObject { @@ -35,13 +35,13 @@ public: void load(class PycData* stream, class PycModule* mod) override; int size() const { return m_size; } - const std::list& value() const { return m_value; } + const std::vector& value() const { return m_value; } std::string repr() const; private: int m_size; - std::list m_value; + std::vector m_value; }; class PycFloat : public PycObject { diff --git a/pyc_sequence.cpp b/pyc_sequence.cpp index e1e9ca2..ba5e8d7 100644 --- a/pyc_sequence.cpp +++ b/pyc_sequence.cpp @@ -24,9 +24,9 @@ bool PycTuple::isEqual(PycRef obj) const PycRef tupleObj = obj.cast(); if (m_size != tupleObj->m_size) return false; - value_t::const_iterator it1 = m_values.begin(); - value_t::const_iterator it2 = tupleObj->m_values.begin(); - while (it1 != m_values.end()) { + auto it1 = m_values.cbegin(); + auto it2 = tupleObj->m_values.cbegin(); + while (it1 != m_values.cend()) { if (!(*it1)->isEqual(*it2)) return false; ++it1, ++it2; @@ -51,9 +51,9 @@ bool PycList::isEqual(PycRef obj) const PycRef listObj = obj.cast(); if (m_size != listObj->m_size) return false; - value_t::const_iterator it1 = m_values.begin(); - value_t::const_iterator it2 = listObj->m_values.begin(); - while (it1 != m_values.end()) { + auto it1 = m_values.cbegin(); + auto it2 = listObj->m_values.cbegin(); + while (it1 != m_values.cend()) { if (!(*it1)->isEqual(*it2)) return false; ++it1, ++it2; @@ -61,20 +61,6 @@ bool PycList::isEqual(PycRef obj) const return true; } -PycRef PycList::get(int idx) const -{ - if (idx < 0) - throw std::out_of_range("List index out of range"); - - value_t::const_iterator it = m_values.begin(); - while (idx-- && it != m_values.end()) - ++it; - if (it == m_values.end()) - throw std::out_of_range("List index out of range"); - return *it; -} - - /* PycDict */ void PycDict::load(PycData* stream, PycModule* mod) @@ -99,17 +85,17 @@ bool PycDict::isEqual(PycRef obj) const if (m_size != dictObj->m_size) return false; - key_t::const_iterator ki1 = m_keys.begin(); - key_t::const_iterator ki2 = dictObj->m_keys.begin(); - while (ki1 != m_keys.end()) { + auto ki1 = m_keys.cbegin(); + auto ki2 = dictObj->m_keys.cbegin(); + while (ki1 != m_keys.cend()) { if (!(*ki1)->isEqual(*ki2)) return false; ++ki1, ++ki2; } - value_t::const_iterator vi1 = m_values.begin(); - value_t::const_iterator vi2 = dictObj->m_values.begin(); - while (vi1 != m_values.end()) { + auto vi1 = m_values.cbegin(); + auto vi2 = dictObj->m_values.cbegin(); + while (vi1 != m_values.cend()) { if (!(*vi1)->isEqual(*vi2)) return false; ++vi1, ++vi2; @@ -119,14 +105,14 @@ bool PycDict::isEqual(PycRef obj) const PycRef PycDict::get(PycRef key) const { - key_t::const_iterator ki = m_keys.begin(); - value_t::const_iterator vi = m_values.begin(); - while (ki != m_keys.end()) { + auto ki = m_keys.cbegin(); + auto vi = m_values.cbegin(); + while (ki != m_keys.cend()) { if ((*ki)->isEqual(key)) return *vi; ++ki, ++vi; } - return NULL; // Disassembly shouldn't get non-existant keys + return NULL; // Disassembly shouldn't get non-existent keys } PycRef PycDict::get(int idx) const @@ -134,10 +120,10 @@ PycRef PycDict::get(int idx) const if (idx < 0) throw std::out_of_range("Dict index out of range"); - value_t::const_iterator it = m_values.begin(); - while (idx-- && it != m_values.end()) + auto it = m_values.cbegin(); + while (idx-- && it != m_values.cend()) ++it; - if (it == m_values.end()) + if (it == m_values.cend()) throw std::out_of_range("Dict index out of range"); return *it; } @@ -159,9 +145,9 @@ bool PycSet::isEqual(PycRef obj) const PycRef setObj = obj.cast(); if (m_size != setObj->m_size) return false; - value_t::const_iterator it1 = m_values.begin(); - value_t::const_iterator it2 = setObj->m_values.begin(); - while (it1 != m_values.end()) { + auto it1 = m_values.cbegin(); + auto it2 = setObj->m_values.cbegin(); + while (it1 != m_values.cend()) { if (!(*it1)->isEqual(*it2)) return false; ++it1, ++it2; @@ -174,10 +160,10 @@ PycRef PycSet::get(int idx) const if (idx < 0) throw std::out_of_range("Set index out of range"); - value_t::const_iterator it = m_values.begin(); - while (idx-- && it != m_values.end()) + auto it = m_values.cbegin(); + while (idx-- && it != m_values.cend()) ++it; - if (it == m_values.end()) + if (it == m_values.cend()) throw std::out_of_range("Set index out of range"); return *it; } diff --git a/pyc_sequence.h b/pyc_sequence.h index 5d033bf..3a97af3 100644 --- a/pyc_sequence.h +++ b/pyc_sequence.h @@ -3,7 +3,6 @@ #include "pyc_object.h" #include -#include #include class PycSequence : public PycObject { @@ -19,7 +18,7 @@ protected: class PycTuple : public PycSequence { public: - typedef std::vector > value_t; + typedef std::vector> value_t; PycTuple(int type = TYPE_TUPLE) : PycSequence(type) { } @@ -36,7 +35,7 @@ private: class PycList : public PycSequence { public: - typedef std::list > value_t; + typedef std::vector> value_t; PycList(int type = TYPE_LIST) : PycSequence(type) { } @@ -45,7 +44,7 @@ public: void load(class PycData* stream, class PycModule* mod) override; const value_t& values() const { return m_values; } - PycRef get(int idx) const override; + PycRef get(int idx) const override { return m_values.at(idx); } private: value_t m_values; @@ -53,8 +52,8 @@ private: class PycDict : public PycSequence { public: - typedef std::list > key_t; - typedef std::list > value_t; + typedef std::vector> key_t; + typedef std::vector> value_t; PycDict(int type = TYPE_DICT) : PycSequence(type) { } @@ -75,7 +74,7 @@ private: class PycSet : public PycSequence { public: - typedef std::set > value_t; + typedef std::set> value_t; PycSet(int type = TYPE_SET) : PycSequence(type) { }