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

[PoC] Experimental Rust parser + benchmark #5196

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Dockerfile
49 changes: 49 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
FROM debian:bookworm-slim

SHELL ["/bin/bash","-l","-c"]

ENV DEBIAN_FRONTEND=noninteractive

# Libs

RUN apt-get update && apt-get install -y \
curl \
gnupg \
build-essential \
&& rm -rf /var/lib/apt/lists/*

RUN apt-get update && apt-get install -y libclang-dev

RUN apt-get install ghostscript shared-mime-info openssl curl gnupg2 dirmngr git-core libcurl4-openssl-dev software-properties-common zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libffi-dev libpq-dev libmagickcore-6.q16-dev -y

# Rust

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
&& chmod +x $HOME/.cargo/bin/rustc

# Ruby (rbenv)

RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv
RUN echo 'export PATH="~/.rbenv/bin:$PATH"' >> ~/.bashrc
RUN echo 'eval "$(rbenv init -)"' >> ~/.bashrc

RUN git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
RUN echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc

ENV PATH="${HOME}/.rbenv/plugins/ruby-build/bin:${HOME}/.rbenv/bin:${PATH}"

RUN rbenv install 3.3.6
RUN rbenv global 3.3.6

# Benchmark

WORKDIR /app

COPY . .

RUN bundle config set without 'jekyll-plugins' && bundle install
RUN bundle exec rake clobber compile

ENV PATH="/root/.cargo/bin:${PATH}"
RUN cd rust_graphql_parser && bundle install && bundle exec rake clobber compile && cd ..
CMD ["/root/.rbenv/shims/bundle", "exec", "ruby", "--yjit", "/app/benchmark/parser_benchmark.rb"]
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ gem 'pry'
gem 'pry-stack_explorer', platform: :ruby
gem 'pry-byebug'

gem 'rust_graphql_parser', path: 'rust_graphql_parser'

if RUBY_VERSION >= "3.0"
gem "libev_scheduler"
gem "evt"
Expand Down
33 changes: 33 additions & 0 deletions benchmark/parser_benchmark.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require "benchmark/ips"
require "graphql/c_parser"
require 'rust_graphql_parser'
require "memory_profiler"

BENCHMARK_PATH = File.expand_path("../", __FILE__)
BIG_QUERY_STRING = File.read(File.join(BENCHMARK_PATH, "big_query.graphql"))
BIG_QUERY = GraphQL.parse(BIG_QUERY_STRING)

def rust_parse(query)
GraphQL.default_parser = RustGraphqlParserWrapper
GraphQL.parse(BIG_QUERY_STRING)
end

def ruby_parse(query)
GraphQL.default_parser = GraphQL::Language::Parser
GraphQL.parse(BIG_QUERY_STRING)
end

def c_parse(query)
GraphQL.default_parser = GraphQL::CParser
GraphQL.parse(BIG_QUERY_STRING)
end

# Sanity check.
raise "output mismatch" unless rust_parse(BIG_QUERY) == ruby_parse(BIG_QUERY)

Benchmark.ips(time: 30) do |x|
x.report("parsing - Rust") { rust_parse(BIG_QUERY) }
x.report("parsing - C") { c_parse(BIG_QUERY) }
x.report("parsing - Ruby") { ruby_parse(BIG_QUERY) }
x.compare!
end
6 changes: 5 additions & 1 deletion benchmark/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ def self.run(task)
x.report("scan - big query") { GraphQL.scan_with_ruby(BIG_QUERY_STRING) }
when "parse"
# Uncomment this to use the C parser:
# require "graphql/c_parser"
require "graphql/c_parser"
require 'rust_graphql_parser'
GraphQL.default_parser = GraphQL::Language::Parser
# GraphQL.default_parser = GraphQL::CParser
# GraphQL.default_parser = YetAnotherParser
x.report("parse - introspection") { GraphQL.parse(QUERY_STRING) }
x.report("parse - fragments") { GraphQL.parse(ABSTRACT_FRAGMENTS_2_QUERY_STRING) }
x.report("parse - big query") { GraphQL.parse(BIG_QUERY_STRING) }
Expand Down
17 changes: 17 additions & 0 deletions rust_graphql_parser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
target/

# rspec failure tracking
.rspec_status
3 changes: 3 additions & 0 deletions rust_graphql_parser/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--format documentation
--color
--require spec_helper
13 changes: 13 additions & 0 deletions rust_graphql_parser/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
AllCops:
TargetRubyVersion: 2.6

Style/StringLiterals:
Enabled: true
EnforcedStyle: double_quotes

Style/StringLiteralsInInterpolation:
Enabled: true
EnforcedStyle: double_quotes

Layout/LineLength:
Max: 120
Loading
Loading