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

IOBuffer back to Ruby #1980

Merged
merged 2 commits into from
Feb 27, 2020
Merged

IOBuffer back to Ruby #1980

merged 2 commits into from
Feb 27, 2020

Conversation

nateberkopec
Copy link
Member

File under "weird idea".

@nateberkopec nateberkopec added this to the 5.0.0 milestone Sep 23, 2019
end

def append(*args)
args.each { |a| concat(a) }
Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW, Ruby 2.4+ supports multi-args String#concat.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice! We have to support 2.2+ for now.

@eregon
Copy link
Contributor

eregon commented Sep 23, 2019

This looks great to me:
-155 lines of C
-72 lines of Java
+17 lines of Ruby

I guess the main concern is: how does it affect performance?

@nateberkopec
Copy link
Member Author

@eregon Yeah, agree. I've got an open issue on #1981 surrounding that.

@kares
Copy link
Contributor

kares commented Oct 7, 2019

a bit ugly that IOBuffer now has a "full" String API but I guess its not a user API anyway ...

@nateberkopec
Copy link
Member Author

This branch, extra large request body:

  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.96ms    1.02ms  16.99ms   72.38%
    Req/Sec     1.04k    98.31     1.22k    79.08%
  Latency Distribution
     50%    1.90ms
     75%    2.52ms
     90%    3.24ms
     99%    4.86ms
  124562 requests in 1.00m, 127.62GB read
Requests/sec:   2074.35
Transfer/sec:      2.13GB

Master, large request body:

  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.74ms    0.86ms  16.93ms   71.69%
    Req/Sec     1.17k    66.38     1.29k    85.25%
  Latency Distribution
     50%    1.68ms
     75%    2.26ms
     90%    2.81ms
     99%    3.99ms
  139603 requests in 1.00m, 143.03GB read
Requests/sec:   2325.64
Transfer/sec:      2.38GB

This branch, hello world:

  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   242.78us  137.14us   2.63ms   97.29%
    Req/Sec     8.67k   661.24     9.04k    96.52%
  Latency Distribution
     50%  224.00us
     75%  258.00us
     90%  290.00us
     99%    1.06ms
  173345 requests in 10.11s, 12.56MB read
Requests/sec:  17154.11
Transfer/sec:      1.24MB

Master, hello world:

  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   235.08us  135.54us   3.09ms   97.58%
    Req/Sec     8.90k     0.91k    9.36k    98.02%
  Latency Distribution
     50%  217.00us
     75%  251.00us
     90%  283.00us
     99%    1.03ms
  178961 requests in 10.10s, 12.97MB read
Requests/sec:  17715.35
Transfer/sec:      1.28MB

Maybe a 5% slowdown but that's really within the statistical margin of error. I think this is good for a merge.

@nateberkopec
Copy link
Member Author

This appears to just stall the ruby 2.3 build 😖

module Puma
class IOBuffer < String
def initialize
if RUBY_VERSION <= "2.3"
Copy link
Contributor

@eregon eregon Oct 13, 2019

Choose a reason for hiding this comment

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

This condition is incorrect (e.g. 2.3.4 <= 2.3 doesn't hold), use capacity if RUBY_VERSION >= 2.4 should work fine instead, and that's likely what makes the 2.3 build fails:
https://github.com/puma/puma/pull/1980/checks?check_run_id=258129791

/home/runner/work/puma/puma/lib/puma/io_buffer.rb:9:in `initialize': unknown keyword: capacity (ArgumentError)
	from /home/runner/work/puma/puma/lib/puma/io_buffer.rb:9:in `initialize'
	from /home/runner/work/puma/puma/lib/puma/thread_pool.rb:97:in `new'
	from /home/runner/work/puma/puma/lib/puma/thread_pool.rb:97:in `block (2 levels) in spawn_thread'
	from /home/runner/work/puma/puma/lib/puma/thread_pool.rb:97:in `map'
	from /home/runner/work/puma/puma/lib/puma/thread_pool.rb:97:in `block in spawn_thread'

@nateberkopec
Copy link
Member Author

nateberkopec commented Oct 14, 2019

I'm not sure the capacity optimization is worth it. Removed it and it's now benchmarking faster than master, and hello.sh benchmark on this branch is now Requests/sec: 18001.34 vs master Requests/sec: 16311.53. Big response becnhmark is Requests/sec: 2269.64 vs master's Requests/sec: 2191.85. So we are now even or even slightly faster than master branch 😆

EDIT: Those numbers are MRI, I'll go back and check JRuby too before merge.

@nateberkopec nateberkopec marked this pull request as ready for review October 16, 2019 04:17
@headius
Copy link
Contributor

headius commented Nov 11, 2019

@nateberkopec Where are the benchmarks you ran above? I'd like to confirm there's no performance hit on JRuby and see if any tweaks might help improve things further.

@headius
Copy link
Contributor

headius commented Nov 11, 2019

This is failing on JRuby because the HTTP parser ext still references the Java IOBuffer. I'll have a patch shortly.

@headius
Copy link
Contributor

headius commented Nov 11, 2019

Just remove import:

diff --git a/ext/puma_http11/PumaHttp11Service.java b/ext/puma_http11/PumaHttp11Service.java
index da7c2719..00f63aa2 100644
--- a/ext/puma_http11/PumaHttp11Service.java
+++ b/ext/puma_http11/PumaHttp11Service.java
@@ -6,7 +6,6 @@ import org.jruby.Ruby;
 import org.jruby.runtime.load.BasicLibraryService;
 
 import org.jruby.puma.Http11;
-import org.jruby.puma.IOBuffer;
 import org.jruby.puma.MiniSSL;
 
 public class PumaHttp11Service implements BasicLibraryService {

@dentarg
Copy link
Member

dentarg commented Nov 11, 2019

@headius maybe these? https://github.com/puma/puma/tree/v4.3.0/benchmarks/wrk

@headius
Copy link
Contributor

headius commented Nov 11, 2019

On a simple Roda benchmark, this change appears to have no negative performance impact for JRuby. It's within the margin of error for this wrk-driven Roda benchmark. 👍

@nateberkopec nateberkopec added the waiting-for-changes Waiting on changes from the requestor label Feb 21, 2020
@nateberkopec nateberkopec merged commit 510f39d into master Feb 27, 2020
@nateberkopec nateberkopec deleted the io-ruby branch March 14, 2020 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance perf waiting-for-changes Waiting on changes from the requestor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants