several significant speed improvements (removed excessive copying of strings)

This commit is contained in:
John Wiegley 2004-08-17 04:57:38 -04:00
parent 9e235d04a1
commit 325cf53ea7
8 changed files with 86 additions and 118 deletions

View file

@ -42,12 +42,6 @@ all: make.deps ledger
docs: ledger.info ledger.pdf docs: ledger.info ledger.pdf
install:
make clean
make DFLAGS="-O3 -fomit-frame-pointer"
cp ledger $(HOME)/bin
strip $(HOME)/bin/ledger
libledger.a: $(OBJS) libledger.a: $(OBJS)
ar rv $@ $? ar rv $@ $?
ranlib $@ ranlib $@

View file

@ -1,6 +1,5 @@
#include "amount.h" #include "ledger.h"
#include "util.h"
#include <list>
#include "gmp.h" #include "gmp.h"
@ -585,43 +584,30 @@ static inline char peek_next_nonws(std::istream& in)
void parse_quantity(std::istream& in, std::string& value) void parse_quantity(std::istream& in, std::string& value)
{ {
static char buf[256];
char c = peek_next_nonws(in); char c = peek_next_nonws(in);
while (std::isdigit(c) || c == '-' || c == '.' || c == ',') { READ_INTO(in, buf, 256, c,
in.get(c); std::isdigit(c) || c == '-' || c == '.' || c == ',');
if (in.eof()) value = buf;
break;
value += c;
c = in.peek();
}
} }
void parse_commodity(std::istream& in, std::string& symbol) void parse_commodity(std::istream& in, std::string& symbol)
{ {
static char buf[256];
char c = peek_next_nonws(in); char c = peek_next_nonws(in);
if (c == '"') { if (c == '"') {
in.get(c); in.get(c);
c = in.peek(); READ_INTO(in, buf, 256, c, c != '"');
while (! in.eof() && c != '"') {
in.get(c);
if (c == '\\')
in.get(c);
symbol += c;
c = in.peek();
}
if (c == '"') if (c == '"')
in.get(c); in.get(c);
else else
assert(0); assert(0);
} else { } else {
while (! std::isspace(c) && ! std::isdigit(c) && c != '-' && c != '.') { READ_INTO(in, buf, 256, c, ! std::isspace(c) && ! std::isdigit(c) &&
in.get(c); c != '-' && c != '.');
if (in.eof())
break;
symbol += c;
c = in.peek();
}
} }
symbol = buf;
} }
void amount_t::parse(std::istream& in) void amount_t::parse(std::istream& in)

View file

@ -20,8 +20,6 @@ config_t::config_t()
{ {
if (const char * p = std::getenv("HOME")) if (const char * p = std::getenv("HOME"))
init_file = cache_file = price_db = p; init_file = cache_file = price_db = p;
else
init_file = cache_file = price_db = "";
init_file += "/.ledgerrc"; init_file += "/.ledgerrc";
cache_file += "/.ledger"; cache_file += "/.ledger";

View file

@ -47,7 +47,9 @@ element_t * format_t::parse_elements(const std::string& fmt)
{ {
element_t * result = NULL; element_t * result = NULL;
element_t * current = NULL; element_t * current = NULL;
std::string str;
static char buf[1024];
char * q = buf;
for (const char * p = fmt.c_str(); *p; p++) { for (const char * p = fmt.c_str(); *p; p++) {
if (*p == '%') { if (*p == '%') {
@ -58,10 +60,10 @@ element_t * format_t::parse_elements(const std::string& fmt)
current = current->next; current = current->next;
} }
if (! str.empty()) { if (q != buf) {
current->type = element_t::STRING; current->type = element_t::STRING;
current->chars = str; current->chars = std::string(buf, q);
str = ""; q = buf;
current->next = new element_t; current->next = new element_t;
current = current->next; current = current->next;
@ -73,22 +75,23 @@ element_t * format_t::parse_elements(const std::string& fmt)
++p; ++p;
} }
std::string num; int num = 0;
while (*p && std::isdigit(*p)) while (*p && std::isdigit(*p)) {
num += *p++; num *= 10;
if (! num.empty()) num += *p++ - '0';
current->min_width = std::atol(num.c_str()); }
current->min_width = num;
if (*p == '.') { if (*p == '.') {
++p; ++p;
num = ""; num = 0;
while (*p && std::isdigit(*p)) while (*p && std::isdigit(*p)) {
num += *p++; num *= 10;
if (! num.empty()) { num += *p++ - '0';
current->max_width = std::atol(num.c_str());
if (current->min_width == 0)
current->min_width = current->max_width;
} }
current->max_width = num;
if (current->min_width == 0)
current->min_width = current->max_width;
} }
switch (*p) { switch (*p) {
@ -97,29 +100,31 @@ element_t * format_t::parse_elements(const std::string& fmt)
current->chars = "%"; current->chars = "%";
break; break;
case '(': case '(': {
++p; ++p;
num = ""; const char * b = p;
while (*p && *p != ')') while (*p && *p != ')')
num += *p++; p++;
if (*p != ')') if (*p != ')')
throw format_error("Missing ')'"); throw format_error("Missing ')'");
current->type = element_t::VALUE_EXPR; current->type = element_t::VALUE_EXPR;
current->val_expr = parse_value_expr(num); current->val_expr = parse_value_expr(std::string(b, p));
break; break;
}
case '[': case '[': {
++p; ++p;
num = ""; const char * b = p;
while (*p && *p != ']') while (*p && *p != ']')
num += *p++; p++;
if (*p != ']') if (*p != ']')
throw format_error("Missing ']'"); throw format_error("Missing ']'");
current->type = element_t::DATE_STRING; current->type = element_t::DATE_STRING;
current->chars = num; current->chars = std::string(b, p);
break; break;
}
case 'D': case 'D':
current->type = element_t::DATE_STRING; current->type = element_t::DATE_STRING;
@ -137,11 +142,11 @@ element_t * format_t::parse_elements(const std::string& fmt)
case '_': current->type = element_t::SPACER; break; case '_': current->type = element_t::SPACER; break;
} }
} else { } else {
str += *p; *q++ = *p;
} }
} }
if (! str.empty()) { if (q != buf) {
if (! result) { if (! result) {
current = result = new element_t; current = result = new element_t;
} else { } else {
@ -149,7 +154,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
current = current->next; current = current->next;
} }
current->type = element_t::STRING; current->type = element_t::STRING;
current->chars = str; current->chars = std::string(buf, q);
} }
return result; return result;

View file

@ -1,4 +1,5 @@
#include "option.h" #include "option.h"
#include "util.h"
#include <iostream> #include <iostream>
#include <cstdarg> #include <cstdarg>
@ -9,11 +10,16 @@ option_handler::option_handler(const std::string& label,
{ {
option_t opt; option_t opt;
static char buf[128];
char * p = buf;
for (const char * q = label.c_str(); *q; q++) for (const char * q = label.c_str(); *q; q++)
if (*q == '_') if (*q == '_')
opt.long_opt += '-'; *p++ = '-';
else else
opt.long_opt += *q; *p++ = *q;
assert(p < buf + 127);
*p = '\0';
opt.long_opt = buf;
handlers.insert(option_handler_pair(opt.long_opt, this)); handlers.insert(option_handler_pair(opt.long_opt, this));
@ -130,15 +136,18 @@ void process_environment(char ** envp, const std::string& tag)
{ {
for (char ** p = envp; *p; p++) for (char ** p = envp; *p; p++)
if (std::strncmp(*p, tag.c_str(), 7) == 0) { if (std::strncmp(*p, tag.c_str(), 7) == 0) {
std::string opt;
char * q; char * q;
static char buf[128];
char * r = buf;
for (q = *p + 7; *q && *q != '='; q++) for (q = *p + 7; *q && *q != '='; q++)
if (*q == '_') if (*q == '_')
opt += '-'; *r++ += '-';
else else
opt += std::tolower(*q); *r++ += std::tolower(*q);
assert(r < buf + 127);
*r = '\0';
if (*q == '=') if (*q == '=')
process_option(opt, q + 1); process_option(buf, q + 1);
} }
} }

View file

@ -385,13 +385,12 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
in >> c; in >> c;
in >> date; in >> date;
in >> time; in >> time;
date += " ";
date += time;
in.getline(line, MAX_LINE); in.getline(line, MAX_LINE);
linenum++; linenum++;
date += " ";
date += time;
struct std::tm when; struct std::tm when;
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) { if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
entry_t * curr = new entry_t; entry_t * curr = new entry_t;

View file

@ -1,6 +1,8 @@
#include "valexpr.h" #include "valexpr.h"
#include "error.h" #include "error.h"
#include "datetime.h" #include "datetime.h"
#include "debug.h"
#include "util.h"
#include <vector> #include <vector>
@ -344,32 +346,20 @@ value_expr_t * parse_value_term(std::istream& in)
char c = peek_next_nonws(in); char c = peek_next_nonws(in);
if (std::isdigit(c) || c == '.' || c == '{') { if (std::isdigit(c) || c == '.' || c == '{') {
std::string ident; static char buf[2048];
if (c == '{') { if (c == '{') {
in.get(c); in.get(c);
c = in.peek(); READ_INTO(in, buf, 2048, c, c != '}');
while (! in.eof() && c != '}') {
in.get(c);
ident += c;
c = in.peek();
}
if (c == '}') if (c == '}')
in.get(c); in.get(c);
else else
throw value_expr_error("Missing '}'"); throw value_expr_error("Missing '}'");
} else { } else {
while (! in.eof() && std::isdigit(c) || c == '.') { READ_INTO(in, buf, 2048, c, std::isdigit(c) || c == '.');
in.get(c);
ident += c;
c = in.peek();
}
} }
if (! ident.empty()) { node = new value_expr_t(value_expr_t::CONSTANT_A);
node = new value_expr_t(value_expr_t::CONSTANT_A); node->constant_a.parse(buf);
node->constant_a.parse(ident);
}
return node; return node;
} }
@ -443,7 +433,6 @@ value_expr_t * parse_value_term(std::istream& in)
// Other // Other
case '/': { case '/': {
std::string ident;
bool payee_mask = false; bool payee_mask = false;
c = peek_next_nonws(in); c = peek_next_nonws(in);
@ -453,22 +442,15 @@ value_expr_t * parse_value_term(std::istream& in)
c = in.peek(); c = in.peek();
} }
while (! in.eof() && c != '/') { static char buf[4096];
in.get(c); READ_INTO(in, buf, 4096, c, c != '/');
if (c == '\\') if (c != '/')
in.get(c);
ident += c;
c = in.peek();
}
if (c == '/') {
in.get(c);
node = new value_expr_t(payee_mask ?
value_expr_t::F_PAYEE_MASK : value_expr_t::F_ACCOUNT_MASK);
node->mask = new mask_t(ident);
} else {
throw value_expr_error("Missing closing '/'"); throw value_expr_error("Missing closing '/'");
}
in.get(c);
node = new value_expr_t(payee_mask ? value_expr_t::F_PAYEE_MASK :
value_expr_t::F_ACCOUNT_MASK);
node->mask = new mask_t(buf);
break; break;
} }
@ -481,22 +463,15 @@ value_expr_t * parse_value_term(std::istream& in)
break; break;
case '[': { case '[': {
std::string ident; static char buf[1024];
READ_INTO(in, buf, 1024, c, c != ']');
c = in.peek(); if (c != ']')
while (! in.eof() && c != ']') {
in.get(c);
ident += c;
c = in.peek();
}
if (c == ']') {
in.get(c);
node = new value_expr_t(value_expr_t::CONSTANT_T);
if (! parse_date(ident.c_str(), &node->constant_t))
throw value_expr_error("Failed to parse date");
} else {
throw value_expr_error("Missing ']'"); throw value_expr_error("Missing ']'");
}
in.get(c);
node = new value_expr_t(value_expr_t::CONSTANT_T);
if (! parse_date(buf, &node->constant_t))
throw value_expr_error("Failed to parse date");
break; break;
} }

View file

@ -133,9 +133,11 @@ class item_predicate
predicate = NULL; predicate = NULL;
if (! _predicate.empty()) { if (! _predicate.empty()) {
try { try {
#ifdef DEBUG_ENABLED
DEBUG_CLASS("valexpr.predicate.parse"); DEBUG_CLASS("valexpr.predicate.parse");
DEBUG_PRINT_("parsing: '" << _predicate << "'"); DEBUG_PRINT_("parsing: '" << _predicate << "'");
#endif
predicate = parse_value_expr(_predicate); predicate = parse_value_expr(_predicate);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED