use custom csv writer for performance
This commit is contained in:
@@ -9,10 +9,13 @@ class PdbFile {
|
|||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
|
|
||||||
|
private final long offsetInEpochMilli;
|
||||||
|
|
||||||
public PdbFile(final Day day, final File file, final Tags tags) {
|
public PdbFile(final Day day, final File file, final Tags tags) {
|
||||||
this.day = day;
|
this.day = day;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
|
offsetInEpochMilli = day.getOffsetInEpochMilli();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PdbFile today(final File file, final Tags tags) {
|
public static PdbFile today(final File file, final Tags tags) {
|
||||||
@@ -38,7 +41,7 @@ class PdbFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long getOffsetInEpochMilli() {
|
public long getOffsetInEpochMilli() {
|
||||||
return getTimeRange().getFrom().toInstant().toEpochMilli();
|
return offsetInEpochMilli;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ public class PdbFileIterator implements Iterator<Entry>, AutoCloseable {
|
|||||||
if (reader == null) {
|
if (reader == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Optional<Entry> optionalEntry = reader.readEntry(currentPdbFile.getTags());
|
final Entry entry = reader.readNullableEntry(currentPdbFile.getTags());
|
||||||
|
|
||||||
return optionalEntry.orElseGet(() -> {
|
if (entry == null) {
|
||||||
nextFile();
|
nextFile();
|
||||||
if (reader == null) {
|
if (reader == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -44,7 +44,9 @@ public class PdbFileIterator implements Iterator<Entry>, AutoCloseable {
|
|||||||
final Tags tags = currentPdbFile.getTags();
|
final Tags tags = currentPdbFile.getTags();
|
||||||
return reader.readEntry(tags).orElse(null);
|
return reader.readEntry(tags).orElse(null);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ class PdbReader implements AutoCloseable {
|
|||||||
* @return the value or -1 if end of stream has been reached
|
* @return the value or -1 if end of stream has been reached
|
||||||
*/
|
*/
|
||||||
public long readValue() {
|
public long readValue() {
|
||||||
assertPositionIsAValuePosition();
|
|
||||||
|
|
||||||
return read();
|
return read();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,13 +40,11 @@ class PdbReader implements AutoCloseable {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public long readEpochMilli() {
|
public long readEpochMilli() {
|
||||||
assertPositionIsADatePosition();
|
|
||||||
|
|
||||||
final long value = read();
|
final long value = read();
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return pdbFile.getDay().getOffsetInEpochMilli() + value;
|
return pdbFile.getOffsetInEpochMilli() + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OffsetDateTime readDate() {
|
public OffsetDateTime readDate() {
|
||||||
@@ -65,11 +61,12 @@ class PdbReader implements AutoCloseable {
|
|||||||
try {
|
try {
|
||||||
final int read = data.read(buffer);
|
final int read = data.read(buffer);
|
||||||
|
|
||||||
if (read < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (read != BYTES_PER_VALUE) {
|
if (read != BYTES_PER_VALUE) {
|
||||||
throw new IllegalStateException("invalid file");
|
if (read < 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("invalid file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return BitFiddling.makeLong(buffer[0], buffer[1], buffer[2], buffer[3]);
|
return BitFiddling.makeLong(buffer[0], buffer[1], buffer[2], buffer[3]);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
@@ -77,40 +74,6 @@ class PdbReader implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertPositionIsADatePosition() {
|
|
||||||
try {
|
|
||||||
assertPositionIsValid();
|
|
||||||
|
|
||||||
if ((data.getFilePointer() / BYTES_PER_VALUE) % 2 != 0) {
|
|
||||||
throw new IllegalStateException("file pointer is not at a date position: " + data.getFilePointer());
|
|
||||||
}
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new ReadRuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertPositionIsAValuePosition() {
|
|
||||||
assertPositionIsValid();
|
|
||||||
try {
|
|
||||||
if ((data.getFilePointer() / BYTES_PER_VALUE) % 2 != 1) {
|
|
||||||
throw new IllegalStateException("file pointer is not at a value position: " + data.getFilePointer());
|
|
||||||
}
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new ReadRuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertPositionIsValid() {
|
|
||||||
try {
|
|
||||||
if (data.getFilePointer() % BYTES_PER_VALUE != 0) {
|
|
||||||
throw new IllegalStateException("file pointer is at an illegal position. It is at "
|
|
||||||
+ data.getFilePointer() + " which is not divisible by " + BYTES_PER_VALUE);
|
|
||||||
}
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new ReadRuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seek to the n-th value.
|
* Seek to the n-th value.
|
||||||
*
|
*
|
||||||
@@ -183,17 +146,22 @@ class PdbReader implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Entry> readEntry(final Tags tags) throws ReadRuntimeException {
|
Entry readNullableEntry(final Tags tags) throws ReadRuntimeException {
|
||||||
final long epochMilli = readEpochMilli();
|
final long epochMilli = readEpochMilli();
|
||||||
if (epochMilli < 0) {
|
if (epochMilli < 0) {
|
||||||
return Optional.empty();
|
return null;
|
||||||
}
|
}
|
||||||
final long value = readValue();
|
final long value = readValue();
|
||||||
|
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
return Optional.empty();
|
return null;
|
||||||
}
|
}
|
||||||
return Optional.of(new Entry(epochMilli, value, tags));
|
return new Entry(epochMilli, value, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Entry> readEntry(final Tags tags) throws ReadRuntimeException {
|
||||||
|
|
||||||
|
return Optional.ofNullable(readNullableEntry(tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,13 @@ public class Gnuplot {
|
|||||||
final File gnuplotFile = File.createTempFile("gnuplot", ".dem", tmpDirectory.toFile());
|
final File gnuplotFile = File.createTempFile("gnuplot", ".dem", tmpDirectory.toFile());
|
||||||
Files.write(gnuplotFileContent, gnuplotFile, StandardCharsets.UTF_8);
|
Files.write(gnuplotFileContent, gnuplotFile, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
final long start = System.nanoTime();
|
||||||
|
|
||||||
final ProcessBuilder processBuilder = new ProcessBuilder("gnuplot", gnuplotFile.getAbsolutePath());
|
final ProcessBuilder processBuilder = new ProcessBuilder("gnuplot", gnuplotFile.getAbsolutePath());
|
||||||
processBuilder.inheritIO();
|
processBuilder.inheritIO();
|
||||||
final Process start = processBuilder.start();
|
final Process process = processBuilder.start();
|
||||||
start.waitFor();
|
process.waitFor();
|
||||||
|
|
||||||
|
System.out.println("gnuplot: " + (System.nanoTime() - start) / 1_000_000.0 + "ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package org.lucares.recommind.logs;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@@ -15,10 +18,6 @@ import java.util.stream.Stream;
|
|||||||
import org.lucares.performance.db.Entry;
|
import org.lucares.performance.db.Entry;
|
||||||
import org.lucares.performance.db.FileUtils;
|
import org.lucares.performance.db.FileUtils;
|
||||||
import org.lucares.performance.db.PerformanceDb;
|
import org.lucares.performance.db.PerformanceDb;
|
||||||
import org.lucares.tanga.svak.StreamSvWriter;
|
|
||||||
import org.lucares.tanga.svak.StreamSvWriterSettings;
|
|
||||||
import org.lucares.tanga.svak.StreamSvWriterSettings.Escaping;
|
|
||||||
import org.lucares.tanga.svak.StreamSvWriterSettings.FieldQuoting;
|
|
||||||
|
|
||||||
public class Plotter {
|
public class Plotter {
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
@@ -54,11 +53,11 @@ public class Plotter {
|
|||||||
|
|
||||||
private static void toCsv(final Stream<Entry> entries, final File dataFile) throws IOException {
|
private static void toCsv(final Stream<Entry> entries, final File dataFile) throws IOException {
|
||||||
|
|
||||||
final StreamSvWriterSettings svSettings = new StreamSvWriterSettings(",", "'");
|
final long start = System.nanoTime();
|
||||||
svSettings.setFieldQuoting(FieldQuoting.IF_NEEDED);
|
int count = 0;
|
||||||
svSettings.setEscaping(Escaping.NONE);
|
final int separator = ',';
|
||||||
try (FileOutputStream output = new FileOutputStream(dataFile);
|
final int newline = '\n';
|
||||||
StreamSvWriter writer = new StreamSvWriter(output, svSettings)) {
|
try (final Writer output = new OutputStreamWriter(new FileOutputStream(dataFile), StandardCharsets.US_ASCII);) {
|
||||||
|
|
||||||
final Iterator<Entry> it = entries.iterator();
|
final Iterator<Entry> it = entries.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
@@ -66,8 +65,13 @@ public class Plotter {
|
|||||||
|
|
||||||
final String value = String.valueOf(entry.getValue());
|
final String value = String.valueOf(entry.getValue());
|
||||||
final String date = entry.getDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
final String date = entry.getDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
||||||
writer.writeLine(date, value);
|
output.write(date);
|
||||||
|
output.write(separator);
|
||||||
|
output.write(value);
|
||||||
|
output.write(newline);
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
System.out.println("wrote " + count + " values to csv in: " + (System.nanoTime() - start) / 1_000_000.0 + "ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user