Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARROW-3666: [C++] Improve C++ parser performance #2886

Closed
wants to merge 2 commits into from

Conversation

pitrou
Copy link
Member

@pitrou pitrou commented Oct 31, 2018

Make CSV parsing around 30% faster.

Benchmark of reading a CSV file with integer columns. Before:

  • multi-threaded: 1.2 GB/s
  • single-threaded: 190 MB/s

After:

  • multi-threaded: 1.6 GB/s
  • single-threaded: 210 MB/s

(on a 8-core 16-thread AMD Ryzen CPU)

@pitrou
Copy link
Member Author

pitrou commented Oct 31, 2018

I'm open to suggestions so as to make this more readable and maintainable. Should probably add some comments.

@pitrou
Copy link
Member Author

pitrou commented Oct 31, 2018

For the record, we're about 30% faster than Paratext when reading a CSV file of floating-point numbers. Even if we call to_pandas() on the result, we're still slightly faster.

As for other types (binary, ints), Paratext seems either broken or insanely slow on those.

@codecov-io
Copy link

codecov-io commented Oct 31, 2018

Codecov Report

❗ No coverage uploaded for pull request base (master@2cdc4d4). Click here to learn what that means.
The diff coverage is 96.64%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #2886   +/-   ##
=========================================
  Coverage          ?   87.27%           
=========================================
  Files             ?      404           
  Lines             ?    63056           
  Branches          ?        0           
=========================================
  Hits              ?    55031           
  Misses            ?     7931           
  Partials          ?       94
Impacted Files Coverage Δ
cpp/src/arrow/csv/reader.cc 88.82% <100%> (ø)
cpp/src/arrow/csv/parser.h 100% <100%> (ø)
cpp/src/arrow/csv/parser.cc 95.45% <96.36%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2cdc4d4...73b38ed. Read the comment docs.

Copy link
Member

@wesm wesm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comments. You might be able to avoid reallocs when resizing buffers with Resize(n, false).

I would have to spend some more time examining this code to think about how to refactor for readability / maintainability, but so long as we have enough micro/macrobenchmarks to be able to refactor without fear of performance regressions, I am OK moving forward since there are so many features we'll need to build in this module

}

void Finish(std::shared_ptr<Buffer>* out_parsed) {
ARROW_CHECK_OK(parsed_buffer_->Resize(parsed_size_));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might pass shrink_to_fit=false to avoid realloc here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to make much of a difference though. Shrinking may help reduce the memory footprint a bit.


while (data < data_end && num_rows_ < max_num_rows_) {
template <typename SpecializedOptions, typename ValuesWriter, typename ParsedWriter>
Status BlockParser::ParseChunk(ValuesWriter& values_writer, ParsedWriter& parsed_writer,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using T* instead of T& for these first two arguments

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

@wesm
Copy link
Member

wesm commented Nov 4, 2018

Is the improved performance here mostly from the memory optimization in the presized case?

Makes CSV parsing around 30% faster
@pitrou
Copy link
Member Author

pitrou commented Nov 5, 2018

Is the improved performance here mostly from the memory optimization in the presized case?

Not only, I think it's also simpler code being generated. CSV parsing has a lot of data-dependent branching in its critical path. I don't know how reliable the numbers are, but perf stat reports more than one billion branches per second in single-threaded mode.

@pitrou
Copy link
Member Author

pitrou commented Nov 5, 2018

+1, will merge.

@pitrou pitrou closed this in 67a436a Nov 5, 2018
@pitrou pitrou deleted the ARROW-3666-faster-csv-parser branch November 5, 2018 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants