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
install:
make clean
make DFLAGS="-O3 -fomit-frame-pointer"
cp ledger $(HOME)/bin
strip $(HOME)/bin/ledger
libledger.a: $(OBJS)
ar rv $@ $?
ranlib $@

View file

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

View file

@ -20,8 +20,6 @@ config_t::config_t()
{
if (const char * p = std::getenv("HOME"))
init_file = cache_file = price_db = p;
else
init_file = cache_file = price_db = "";
init_file += "/.ledgerrc";
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 * current = NULL;
std::string str;
static char buf[1024];
char * q = buf;
for (const char * p = fmt.c_str(); *p; p++) {
if (*p == '%') {
@ -58,10 +60,10 @@ element_t * format_t::parse_elements(const std::string& fmt)
current = current->next;
}
if (! str.empty()) {
if (q != buf) {
current->type = element_t::STRING;
current->chars = str;
str = "";
current->chars = std::string(buf, q);
q = buf;
current->next = new element_t;
current = current->next;
@ -73,23 +75,24 @@ element_t * format_t::parse_elements(const std::string& fmt)
++p;
}
std::string num;
while (*p && std::isdigit(*p))
num += *p++;
if (! num.empty())
current->min_width = std::atol(num.c_str());
int num = 0;
while (*p && std::isdigit(*p)) {
num *= 10;
num += *p++ - '0';
}
current->min_width = num;
if (*p == '.') {
++p;
num = "";
while (*p && std::isdigit(*p))
num += *p++;
if (! num.empty()) {
current->max_width = std::atol(num.c_str());
num = 0;
while (*p && std::isdigit(*p)) {
num *= 10;
num += *p++ - '0';
}
current->max_width = num;
if (current->min_width == 0)
current->min_width = current->max_width;
}
}
switch (*p) {
case '%':
@ -97,29 +100,31 @@ element_t * format_t::parse_elements(const std::string& fmt)
current->chars = "%";
break;
case '(':
case '(': {
++p;
num = "";
const char * b = p;
while (*p && *p != ')')
num += *p++;
p++;
if (*p != ')')
throw format_error("Missing ')'");
current->type = element_t::VALUE_EXPR;
current->val_expr = parse_value_expr(num);
current->val_expr = parse_value_expr(std::string(b, p));
break;
}
case '[':
case '[': {
++p;
num = "";
const char * b = p;
while (*p && *p != ']')
num += *p++;
p++;
if (*p != ']')
throw format_error("Missing ']'");
current->type = element_t::DATE_STRING;
current->chars = num;
current->chars = std::string(b, p);
break;
}
case 'D':
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;
}
} else {
str += *p;
*q++ = *p;
}
}
if (! str.empty()) {
if (q != buf) {
if (! result) {
current = result = new element_t;
} else {
@ -149,7 +154,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
current = current->next;
}
current->type = element_t::STRING;
current->chars = str;
current->chars = std::string(buf, q);
}
return result;

View file

@ -1,4 +1,5 @@
#include "option.h"
#include "util.h"
#include <iostream>
#include <cstdarg>
@ -9,11 +10,16 @@ option_handler::option_handler(const std::string& label,
{
option_t opt;
static char buf[128];
char * p = buf;
for (const char * q = label.c_str(); *q; q++)
if (*q == '_')
opt.long_opt += '-';
*p++ = '-';
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));
@ -130,15 +136,18 @@ void process_environment(char ** envp, const std::string& tag)
{
for (char ** p = envp; *p; p++)
if (std::strncmp(*p, tag.c_str(), 7) == 0) {
std::string opt;
char * q;
static char buf[128];
char * r = buf;
for (q = *p + 7; *q && *q != '='; q++)
if (*q == '_')
opt += '-';
*r++ += '-';
else
opt += std::tolower(*q);
*r++ += std::tolower(*q);
assert(r < buf + 127);
*r = '\0';
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 >> date;
in >> time;
date += " ";
date += time;
in.getline(line, MAX_LINE);
linenum++;
date += " ";
date += time;
struct std::tm when;
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
entry_t * curr = new entry_t;

View file

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

View file

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