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

Add support for zero copy header parsing #9

Closed
misalcedo opened this issue Dec 11, 2021 · 13 comments · Fixed by #10
Closed

Add support for zero copy header parsing #9

misalcedo opened this issue Dec 11, 2021 · 13 comments · Fixed by #10
Assignees
Labels
enhancement New feature or request

Comments

@misalcedo
Copy link
Owner

misalcedo commented Dec 11, 2021

Currently, creating a header clones all of the information into a struct that owns the cloned bits.

An alternative would be to have a struct with the same lifetime as the input source that could be turned into an owned version as needed.

This would be beneficial in cases where you only need a subset of fields as owned values or don't need the header past the input's lifetime.

See https://doc.rust-lang.org/std/borrow/trait.ToOwned.html

Lastly, would be useful to separate the header into an enum with different structs for version 1 vs. 2. Version 1 is much simpler as it lacks TLV support.

@misalcedo misalcedo added the enhancement New feature or request label Dec 11, 2021
@misalcedo misalcedo changed the title Add support for zero copy header paraing Add support for zero copy header parsing Dec 13, 2021
@misalcedo
Copy link
Owner Author

Completed the implementation of version 2.0 for the text protocol. Tests, benchmarks, and documentation are also in place.

Next step is doing the same thing for the binary format.

@misalcedo misalcedo self-assigned this Dec 17, 2021
@misalcedo
Copy link
Owner Author

misalcedo commented Dec 17, 2021

Also, need to update the benchmarks to use groups to reduce repetition

@misalcedo
Copy link
Owner Author

misalcedo commented Dec 17, 2021

Description

Benchmarks run on a 4-core CodeSpace for the text format of the PROXY protocol to compare version 1.X to version 2.0 of this library.

Run with

cargo clean
cargo bench --bench text

Results

ppp text tcp4           time:   [260.37 ns 263.75 ns 267.50 ns]                          
ppp v2 text tcp4        time:   [246.77 ns 249.58 ns 253.18 ns]                             

ppp text tcp6           time:   [540.65 ns 549.96 ns 560.46 ns]                           
ppp v2 text tcp6        time:   [563.97 ns 568.39 ns 573.90 ns]                              

ppp text tcp6 compact   time:   [423.18 ns 430.20 ns 437.74 ns]                                  
ppp v2 text tcp6 compact                                                                            
                        time:   [421.68 ns 426.35 ns 431.81 ns]

ppp header to text tcp4 time:   [253.92 ns 258.40 ns 263.87 ns]                                    
ppp v2 header to text tcp4                                                                             
                        time:   [34.776 ns 35.219 ns 35.768 ns]
ppp v2 addresses to text tcp4  
                        time:   [266.92 ns 270.62 ns 275.02 ns]

ppp header to text tcp6 time:   [545.64 ns 553.35 ns 562.49 ns]                                     
ppp v2 header to text tcp6                                                                             
                        time:   [38.176 ns 38.521 ns 38.910 ns]
ppp v2 addresses to text tcp6                                                                             
                        time:   [633.37 ns 646.07 ns 661.06 ns]

ppp header to text unknown                                                                            
                        time:   [50.763 ns 51.317 ns 51.997 ns]
ppp v2 header to text unknown                                                                             
                        time:   [35.056 ns 35.663 ns 36.375 ns]
ppp v2 addresses to text unknown
                        time:   [31.359 ns 31.745 ns 32.207 ns]

Summary

In every case for parsing, version 2.0 is slightly faster or virtually the same performance.
In every case for displaying, version 2.0 is significantly faster as it maintains a reference to the original header input string.

Even in cases where version 2.0 is slower that is because we turn the string to bytes and have to turn the whole thing back to a UTF8 string. Version 1.x only turned the necessary portions into a UTF8 string and left the rest as bytes. That likely accounts for the slight performance penalty on the longer IPv6 headers.

@misalcedo
Copy link
Owner Author

Need to update the benchmark id's to work with gnuplot

@misalcedo
Copy link
Owner Author

Use starts with for slices in V1 and v2. Implement from for tlv iterator.

@misalcedo
Copy link
Owner Author

Want to implement display for address in V1.
Also, implement various format traits for V2.

@misalcedo
Copy link
Owner Author

Most of the binary format is implemented. I still need to implement the remaining tests. Then, I need to think through how to write a header to binary for using the library during testing. Minimum is: protocol, command, addresses, tlvs.

@misalcedo
Copy link
Owner Author

Remove length property from header in favor of computing the length.

@misalcedo
Copy link
Owner Author

misalcedo commented Dec 19, 2021

Remaining steps:

  • Tests for v2.
  • as_bytes() or equivalent trait implementation for v2.
  • Update Benchmarks.
  • Add builder, tests, and benchmarks.
  • Optimize.
  • streaming support for v1 similar to v2

@misalcedo
Copy link
Owner Author

misalcedo commented Dec 19, 2021

  • Add From impl for addresses to u16
  • add update length to builder
  • add with TLVs and singular to builder
  • add tests for the builder.

@misalcedo
Copy link
Owner Author

misalcedo commented Dec 20, 2021

PPP Binary/v2::Header::try_from/IPv4 with TLVs                                                                             
                        time:   [7.1025 ns 7.1821 ns 7.2757 ns]
PPP Binary/parse_header/IPv4 with TLVs                                                                             
                        time:   [38.795 ns 39.296 ns 39.838 ns]
PPP Binary/v2::Header::try_from/IPv6 without TLVs                                                                             
                        time:   [19.934 ns 20.229 ns 20.577 ns]
PPP Binary/parse_header/IPv6 without TLVs                                                                            
                        time:   [141.57 ns 144.12 ns 147.05 ns]

@misalcedo
Copy link
Owner Author

misalcedo commented Dec 20, 2021

Builder:

  • add set length
  • add with addresses
  • make write tlvs take an into tlv
  • add from for tlv-like tuples
  • add new, with length, padding, and empty to create tlvs.
  • impl write for builder
  • Create to header trait
  • add to bytes default method to trait
  • add from vec for writer, add finish to writer
  • partial result trait with impl for V1 and v2 results
  • examples

@misalcedo
Copy link
Owner Author

misalcedo commented Dec 21, 2021

Remaining tasks:

  • v2 module documentation
  • lib documentation
  • Update README with minimal code sample
  • Update README with reference to examples and how to run them
  • Update README with benchmarking instructions
  • Update README with profiling instructions
  • Support windows compilation
  • Optimize v1 module to at least match the performance of ppp 1.0's text module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant