Skip to content

Commit

Permalink
Merge pull request #8 from machindustries/justinpankmach/optimize-parser
Browse files Browse the repository at this point in the history
do not use their split function
  • Loading branch information
justinpankmach authored Nov 13, 2024
2 parents 7210da5 + cc36039 commit 9d41d2b
Showing 1 changed file with 37 additions and 17 deletions.
54 changes: 37 additions & 17 deletions src/input_output/FGXMLParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,34 +40,57 @@ namespace JSBSim {
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

void FGXMLParse::reset(void)
{
void FGXMLParse::reset(void) {
current_element = document = nullptr;
working_string.erase();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGXMLParse::dumpDataLines(void)
{
void FGXMLParse::dumpDataLines(void) {

if (!working_string.empty()) {
for (auto s: split(working_string, '\n'))
current_element->AddData(s);
//The following change was made by Mach:
// 1. This implemenation iterates over the input string in O(n) time.
// where n is the length of the input string.
// 2. The built in JSBSim split() method runs in O(n^2) for n is the string size, with an additional
// O(m) [for m = n/rows of a matrix] from the outer for loop.
// Overall it runs in O(n^3) time making parsing inviable for files around 90MB+ in size.
// Regression tested against 2 jsbsims with identical inputs, and validated no difference
// within epsilon = 1E-8.
size_t index = 0;
index = working_string.find('\n');
if (index != std::string::npos && index != 0) {
size_t curr = 0;
std::string temp = "";
while (curr < working_string.length()) {
if (working_string[curr] == '\n') {
trim(temp);
current_element->AddData(temp);
temp = "";
} else {
temp.push_back(working_string[curr]);
}
curr++;
}
} else {
trim(working_string);
current_element->AddData(working_string);
}
working_string.erase();
}
working_string.erase();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGXMLParse::startElement (const char * name, const XMLAttributes &atts)
{
void FGXMLParse::startElement(const char *name, const XMLAttributes &atts) {
if (!document) {
document = new Element(name);
current_element = document;
} else {
dumpDataLines();

Element* temp_element = new Element(name);
Element *temp_element = new Element(name);
if (temp_element) {
temp_element->SetParent(current_element);
current_element->AddChildElement(temp_element);
Expand All @@ -84,30 +107,27 @@ void FGXMLParse::startElement (const char * name, const XMLAttributes &atts)
current_element->SetLineNumber(getLine());
current_element->SetFileName(getPath());

for (int i=0; i<atts.size();i++) {
for (int i = 0; i < atts.size(); i++) {
current_element->AddAttribute(atts.getName(i), atts.getValue(i));
}
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGXMLParse::endElement (const char * name)
{
void FGXMLParse::endElement(const char *name) {
dumpDataLines();
current_element = current_element->GetParent();
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGXMLParse::data (const char * s, int length)
{
void FGXMLParse::data(const char *s, int length) {
working_string += string(s, length);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGXMLParse::warning (const char * message, int line, int column)
{
void FGXMLParse::warning(const char *message, int line, int column) {
cerr << "Warning: " << message << " line: " << line << " column: " << column
<< endl;
}
Expand Down

0 comments on commit 9d41d2b

Please sign in to comment.