[Kst] branches/work/kst/portto4/kst/src/datasources/ascii
Peter Kümmel
syntheticpp at gmx.net
Mon Jan 24 16:58:23 CET 2011
SVN commit 1216761 by kuemmel:
AsciiSource: much more inlining
Speedup of this commit:
Delimiters (comment, column) : time
-----------------------------------------------------------
func ptr inlined
No comment, custom: one space : 4.8 3.7
# comment, custom: one space : 5.7 4.2
No comment, whitespace : 6.2 4.0
# comment, whitespace : 6.9 4.2
M +53 -22 asciisource.cpp
M +59 -18 asciisource.h
--- branches/work/kst/portto4/kst/src/datasources/ascii/asciisource.cpp #1216760:1216761
@@ -30,6 +30,7 @@
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
+#include <iostream>
// Load faster in debug mode:
@@ -435,16 +436,17 @@
} else if (_config._columnType == AsciiSourceConfig::Custom) {
if (_config._columnDelimiter.value().size() == 1) {
MeasureTime t("character");
- _columnDelimiterCharacter = _config._columnDelimiter.value()[0].toAscii();
- return readColumns(v, buffer, bufstart, bufread, col, s, n, &AsciiSource::isColumnDelimiter);
+ const IsCharacter column_del(_config._columnDelimiter.value()[0].toAscii());
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del);
} if (_config._columnDelimiter.value().size() > 1) {
MeasureTime t("string");
- _columnDelimiterString = _config._columnDelimiter.value();
- return readColumns(v, buffer, bufstart, bufread, col, s, n, &AsciiSource::isInColumnDelimiterString);
+ const IsInString column_del(_config._columnDelimiter.value());
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del);
}
} else if (_config._columnType == AsciiSourceConfig::Whitespace) {
MeasureTime t("whitespace");
- return readColumns(v, buffer, bufstart, bufread, col, s, n, &AsciiSource::isWhiteSpace);
+ const IsWhiteSpace column_del;
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del);
}
return 0;
@@ -452,42 +454,69 @@
//-------------------------------------------------------------------------------------------
-int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, DelimiterFunction columnDelemiterFunction)
+template<typename ColumnDelimiter>
+int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n,
+ const ColumnDelimiter& column_del)
{
- LexicalCast lexc;
- lexc.setDecimalSeparator(_config._useDot, _config._localSeparator);
- const QString delimiters = _config._delimiters.value();
- DelimiterFunction commentDelemiterFunction;
-
if (_config._delimiters.value().size() == 0) {
- commentDelemiterFunction = 0;
+ const NoDelimiter comment_del;
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del, comment_del);
} else if (_config._delimiters.value().size() == 1) {
- _commentDelimiterCharacter = _config._delimiters.value()[0].toAscii();
- commentDelemiterFunction = &AsciiSource::isCommentDelimiter;
+ const IsCharacter comment_del(_config._delimiters.value()[0].toAscii());
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del, comment_del);
} else if (_config._delimiters.value().size() > 1) {
- _commentDelimiterString = _config._delimiters.value();
- commentDelemiterFunction = &AsciiSource::isInCommentDelimiterString;
+ const IsInString comment_del(_config._delimiters.value());
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del, comment_del);
}
+ return 0;
+}
+
+template<typename ColumnDelimiter, typename CommentDelimiter>
+int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n,
+ const ColumnDelimiter& column_del, const CommentDelimiter& comment_del)
+{
+ if (_config._columnWidthIsConst) {
+ const AlwaysTrue column_withs_are_const;
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del, comment_del, column_withs_are_const);
+ } else {
+ const AlwaysFalse column_withs_are_not_const;
+ return readColumns(v, buffer, bufstart, bufread, col, s, n, column_del, comment_del, column_withs_are_not_const);
+ }
+}
+
+
+template<typename ColumnDelimiter, typename CommentDelimiter, typename ColumnWidthsAreConst>
+int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n,
+ const ColumnDelimiter& column_del, const CommentDelimiter& comment_del,
+ const ColumnWidthsAreConst& are_column_widths_const)
+{
+ LexicalCast lexc;
+ lexc.setDecimalSeparator(_config._useDot, _config._localSeparator);
+ const QString delimiters = _config._delimiters.value();
+
+ const IsLineBreak isLineBreak;
+
int col_start = -1;
for (int i = 0; i < n; i++, s++) {
bool incol = false;
int i_col = 0;
- if (_config._columnWidthIsConst && col_start != -1) {
+ if (are_column_widths_const()) {
+ if (col_start != -1) {
v[i] = lexc.toDouble(&buffer[0] + _rowIndex[s] + col_start);
continue;
}
+ }
v[i] = Kst::NOPOINT;
- int ch;
- for (ch = _rowIndex[s] - bufstart; ch < bufread; ++ch) {
- if (buffer[ch] == '\n' || buffer[ch] == '\r') {
+ for (int ch = _rowIndex[s] - bufstart; ch < bufread; ++ch) {
+ if (isLineBreak(buffer[ch])) {
break;
- } else if ((this->*columnDelemiterFunction)(buffer[ch])) { //<- check for column start
+ } else if (column_del(buffer[ch])) { //<- check for column start
incol = false;
- } else if (commentDelemiterFunction && (this->*commentDelemiterFunction)(buffer[ch])) {
+ } else if (comment_del(buffer[ch])) {
break;
} else {
if (!incol) {
@@ -495,9 +524,11 @@
++i_col;
if (i_col == col) {
toDouble(lexc, buffer, bufread, ch, &v[i], i);
+ if (are_column_widths_const()) {
if (col_start == -1) {
col_start = ch - _rowIndex[s] + 1;
}
+ }
break;
}
}
--- branches/work/kst/portto4/kst/src/datasources/ascii/asciisource.h #1216760:1216761
@@ -103,38 +103,79 @@
int readFromFile(QFile&, T& buffer, int start, int numberOfBytes, int maximalBytes = -1);
- // column delimiter functions
+ // column and comment delimiter functions
- bool isWhiteSpace(char c) {
- return isspace((unsigned char)c);
+ struct AlwaysTrue {
+ AlwaysTrue() {
}
+ inline bool operator()() const {
+ return true;
+ }
+ };
- char _columnDelimiterCharacter;
- bool isColumnDelimiter(char c) {
- return _columnDelimiterCharacter == c;
+ struct AlwaysFalse {
+ AlwaysFalse() {
}
+ inline bool operator()() const {
+ return false;
+ }
+ };
- QString _columnDelimiterString;
- bool isInColumnDelimiterString(char c) {
- return _columnDelimiterString.contains(c);
+ struct NoDelimiter {
+ NoDelimiter() {
}
+ inline bool operator()(const char) const {
+ return false;
+ }
+ };
+ struct IsWhiteSpace {
+ IsWhiteSpace() {
+ }
+ inline bool operator()(const char c) const {
+ return c == ' ' || c == '\t';
+ }
+ };
- // comment delimiter functions
+ struct IsCharacter {
+ IsCharacter(char c) : character(c) {
+ }
+ const char character;
+ inline bool operator()(const char c) const {
+ return character == c;
+ }
+ };
- char _commentDelimiterCharacter;
- bool isCommentDelimiter(char c) {
- return _commentDelimiterCharacter == c;
+ struct IsInString {
+ IsInString(const QString& s) : str(s) {
}
+ const QString str;
+ inline bool operator()(const char c) const {
+ return str.contains(c);
+ }
+ };
- QString _commentDelimiterString;
- bool isInCommentDelimiterString(char c) {
- return _commentDelimiterString.contains(c);
+ struct IsLineBreak {
+ IsLineBreak() {
}
+ inline bool operator()(const char c) const {
+ return c == '\n' || c == '\r';
+ }
+ };
- typedef bool (AsciiSource::*DelimiterFunction)(char);
- int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, DelimiterFunction);
+ template<typename ColumnDelimiter>
+ int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n,
+ const ColumnDelimiter&);
+
+ template<typename ColumnDelimiter, typename CommentDelimiter>
+ int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n,
+ const ColumnDelimiter&, const CommentDelimiter&);
+
+ template<typename ColumnDelimiter, typename CommentDelimiter, typename ColumnWidthsAreConst>
+ int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n,
+ const ColumnDelimiter&, const CommentDelimiter&, const ColumnWidthsAreConst&);
+
void toDouble(const LexicalCast& lexc, const char* buffer, int bufread, int ch, double* v, int row);
// TODO remove
More information about the Kst
mailing list