rabbit-slide-naitoh-rubykaigi-2025 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rabbit +2 -0
- speed up using StringScanner.pdf +0 -0
- data/README.md +24 -0
- data/Rakefile +17 -0
- data/config.yaml +25 -0
- data/images/CVE-2024-35176.png +0 -0
- data/images/RubyKaigi2024LT.png +0 -0
- data/images/assets/rubykaigi2025_slide_title.png +0 -0
- data/images/medpeer.png +0 -0
- data/images/medpeer_mission.png +0 -0
- data/images/rexml_x_1797256482272235856.png +0 -0
- data/images/rubykaigi-2019-p35-p78.png +0 -0
- data/images/svg_327.svg +18 -0
- data/images/svg_340_jit_disable.svg +18 -0
- data/images/svg_340_jit_enable.svg +18 -0
- data/images/svg_341.svg +18 -0
- data/images/svg_341_jit_disable.svg +18 -0
- data/images/svg_341_jit_enable.svg +18 -0
- data/pdf/rubykaigi-2025-rubykaigi-2025.pdf +0 -0
- data/rubykaigi-2025.rab +905 -0
- data/theme.rb +15 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eb549e49916b6fc135fdb13bc40f040086225b7ed9bdbda16ac85848cc47e2c0
|
4
|
+
data.tar.gz: b5f837ed07fa0b4cb15c0bcb8019d078de882eeb05357015025c450a4d7243ac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 33c93f39fce4fd0bcffd13582e2833af9bae3044c23fc22dab873243405576b9a393dea919a3eb68bab327ea93da1e72449df1903b60b32cbb04a4198b74d924
|
7
|
+
data.tar.gz: d36f027b063d6445485e153f9ff10701be83029a093f716a88af4ebb377e37aede7626e5b3bad5522c9842085d212424f99dc01f25545c7611146ecc0bbd2678
|
data/.rabbit
ADDED
Binary file
|
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Improvement of REXML and speed up using StringScanner
|
2
|
+
|
3
|
+
https://rubykaigi.org/2025/
|
4
|
+
|
5
|
+
## 作者向け
|
6
|
+
|
7
|
+
### 表示
|
8
|
+
|
9
|
+
rake
|
10
|
+
|
11
|
+
### 公開
|
12
|
+
|
13
|
+
rake publish
|
14
|
+
|
15
|
+
## 閲覧者向け
|
16
|
+
|
17
|
+
### インストール
|
18
|
+
|
19
|
+
gem install rabbit-slide-naitoh-rubykaigi-2025
|
20
|
+
|
21
|
+
### 表示
|
22
|
+
|
23
|
+
rabbit rabbit-slide-naitoh-rubykaigi-2025.gem
|
24
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rabbit/task/slide"
|
2
|
+
|
3
|
+
# Edit ./config.yaml to customize meta data
|
4
|
+
|
5
|
+
spec = nil
|
6
|
+
Rabbit::Task::Slide.new do |task|
|
7
|
+
spec = task.spec
|
8
|
+
# spec.files += Dir.glob("doc/**/*.*")
|
9
|
+
# spec.files -= Dir.glob("private/**/*.*")
|
10
|
+
# spec.add_runtime_dependency("rabbit-theme-YOUR-THEME")
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Tag #{spec.version}"
|
14
|
+
task :tag do
|
15
|
+
sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
|
16
|
+
sh("git", "push", "--tags")
|
17
|
+
end
|
data/config.yaml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
id: rubykaigi-2025
|
3
|
+
base_name: rubykaigi-2025
|
4
|
+
tags:
|
5
|
+
- ruby
|
6
|
+
- rexml
|
7
|
+
presentation_date: 2025-04-17
|
8
|
+
presentation_start_time:
|
9
|
+
presentation_end_time:
|
10
|
+
version: 1.0.0
|
11
|
+
licenses: []
|
12
|
+
slideshare_id:
|
13
|
+
speaker_deck_id:
|
14
|
+
vimeo_id:
|
15
|
+
youtube_id:
|
16
|
+
width: 1440
|
17
|
+
height: 900
|
18
|
+
source_code_uri:
|
19
|
+
author:
|
20
|
+
markup_language: :rd
|
21
|
+
name: NAITOH Jun
|
22
|
+
email: naitoh@gmail.com
|
23
|
+
rubygems_user: naitoh
|
24
|
+
slideshare_user:
|
25
|
+
speaker_deck_user:
|
Binary file
|
Binary file
|
Binary file
|
data/images/medpeer.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/images/svg_327.svg
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="400">
|
2
|
+
<style>
|
3
|
+
.line { fill: none; stroke-width: 2; }
|
4
|
+
.dashed { stroke-dasharray: 5, 5; }
|
5
|
+
.label { font-size: 18px; text-anchor: middle; }
|
6
|
+
.axis { stroke: #000; stroke-width: 1; }
|
7
|
+
.grid { stroke: #ccc; stroke-width: 0.5; }
|
8
|
+
.point { fill-opacity: 0.8; }
|
9
|
+
.title { font-size: 22px; font-weight: bold; text-anchor: middle; }
|
10
|
+
</style>
|
11
|
+
<!-- 軸 -->
|
12
|
+
<line x1="50" y1="350" x2="750" y2="350" class="axis" />
|
13
|
+
<line x1="50" y1="50" x2="50" y2="350" class="axis" />
|
14
|
+
<!-- タイトル -->
|
15
|
+
<text x="400" y="25" class="title">REXML Performance benchmarks</text>
|
16
|
+
<text x="400" y="388" class="label">rexml version</text>
|
17
|
+
<text x="12" y="200" class="label" transform="rotate(-90, 12, 200)">i/s</text>
|
18
|
+
<line x1="50" y1="350.0" x2="750" y2="350.0" class="grid" /><text x="30" y="355.0" class="label" text-anchor="end">16.0</text><line x1="50" y1="288.8888888888889" x2="750" y2="288.8888888888889" class="grid" /><text x="30" y="293.8888888888889" class="label" text-anchor="end">27.0</text><line x1="50" y1="227.77777777777777" x2="750" y2="227.77777777777777" class="grid" /><text x="30" y="232.77777777777777" class="label" text-anchor="end">38.0</text><line x1="50" y1="166.66666666666666" x2="750" y2="166.66666666666666" class="grid" /><text x="30" y="171.66666666666666" class="label" text-anchor="end">49.0</text><line x1="50" y1="105.55555555555557" x2="750" y2="105.55555555555557" class="grid" /><text x="30" y="110.55555555555557" class="label" text-anchor="end">60.0</text><line x1="50" y1="50" x2="50" y2="350" class="grid" /><text x="50" y="370" class="label">3.2.6</text><line x1="190" y1="50" x2="190" y2="350" class="grid" /><text x="190" y="370" class="label">RubyKaigi2024LT</text><line x1="330" y1="50" x2="330" y2="350" class="grid" /><text x="330" y="370" class="label">3.2.7</text><line x1="470" y1="50" x2="470" y2="350" class="grid" /><text x="470" y="370" class="label">3.2.9</text><line x1="610" y1="50" x2="610" y2="350" class="grid" /><text x="610" y="370" class="label">3.4.0</text><line x1="750" y1="50" x2="750" y2="350" class="grid" /><text x="750" y="370" class="label">3.4.1</text><polyline points="50,201.60555555555555 190,50.93888888888887 330,184.33888888888887 470,111.03888888888889 610,106.21666666666667 750,72.82222222222225" class="line dashed" stroke="#4CAF50" /><circle cx="50" cy="201.60555555555555" r="4" fill="#4CAF50" class="point" /><circle cx="190" cy="50.93888888888887" r="4" fill="#4CAF50" class="point" /><circle cx="330" cy="184.33888888888887" r="4" fill="#4CAF50" class="point" /><circle cx="470" cy="111.03888888888889" r="4" fill="#4CAF50" class="point" /><circle cx="610" cy="106.21666666666667" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="72.82222222222225" r="4" fill="#4CAF50" class="point" /><polyline points="50,222.08888888888887 190,94.91111111111113 330,207.19444444444446 470,146.93333333333334 610,120.83333333333334 750,95.17222222222222" class="line dashed" stroke="#2196F3" /><circle cx="50" cy="222.08888888888887" r="4" fill="#2196F3" class="point" /><circle cx="190" cy="94.91111111111113" r="4" fill="#2196F3" class="point" /><circle cx="330" cy="207.19444444444446" r="4" fill="#2196F3" class="point" /><circle cx="470" cy="146.93333333333334" r="4" fill="#2196F3" class="point" /><circle cx="610" cy="120.83333333333334" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="95.17222222222222" r="4" fill="#2196F3" class="point" /><polyline points="50,235.72777777777776 190,129.8888888888889 330,229.7111111111111 470,184.7444444444444 610,157.43333333333334 750,143.47222222222223" class="line dashed" stroke="#FFC107" /><circle cx="50" cy="235.72777777777776" r="4" fill="#FFC107" class="point" /><circle cx="190" cy="129.8888888888889" r="4" fill="#FFC107" class="point" /><circle cx="330" cy="229.7111111111111" r="4" fill="#FFC107" class="point" /><circle cx="470" cy="184.7444444444444" r="4" fill="#FFC107" class="point" /><circle cx="610" cy="157.43333333333334" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="143.47222222222223" r="4" fill="#FFC107" class="point" /><polyline points="50,295.02222222222224 190,245.47222222222223 330,290.01666666666665 470,264.3611111111111 610,263.45 750,250.4" class="line dashed" stroke="#FF5722" /><circle cx="50" cy="295.02222222222224" r="4" fill="#FF5722" class="point" /><circle cx="190" cy="245.47222222222223" r="4" fill="#FF5722" class="point" /><circle cx="330" cy="290.01666666666665" r="4" fill="#FF5722" class="point" /><circle cx="470" cy="264.3611111111111" r="4" fill="#FF5722" class="point" /><circle cx="610" cy="263.45" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="250.4" r="4" fill="#FF5722" class="point" /><polyline points="50,272.55 190,245.02777777777777 330,291.7888888888889 470,276.78333333333336 610,255.09444444444443 750,247.96666666666667" class="line" stroke="#4CAF50" /><circle cx="50" cy="272.55" r="4" fill="#4CAF50" class="point" /><circle cx="190" cy="245.02777777777777" r="4" fill="#4CAF50" class="point" /><circle cx="330" cy="291.7888888888889" r="4" fill="#4CAF50" class="point" /><circle cx="470" cy="276.78333333333336" r="4" fill="#4CAF50" class="point" /><circle cx="610" cy="255.09444444444443" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="247.96666666666667" r="4" fill="#4CAF50" class="point" /><polyline points="50,282.71666666666664 190,247.68888888888893 330,295.72777777777776 470,279.3611111111111 610,257.6333333333333 750,248.61111111111111" class="line" stroke="#2196F3" /><circle cx="50" cy="282.71666666666664" r="4" fill="#2196F3" class="point" /><circle cx="190" cy="247.68888888888893" r="4" fill="#2196F3" class="point" /><circle cx="330" cy="295.72777777777776" r="4" fill="#2196F3" class="point" /><circle cx="470" cy="279.3611111111111" r="4" fill="#2196F3" class="point" /><circle cx="610" cy="257.6333333333333" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="248.61111111111111" r="4" fill="#2196F3" class="point" /><polyline points="50,295.43888888888887 190,271.50555555555553 330,309.7833333333333 470,300.01666666666665 610,280.0333333333333 750,271.06111111111113" class="line" stroke="#FFC107" /><circle cx="50" cy="295.43888888888887" r="4" fill="#FFC107" class="point" /><circle cx="190" cy="271.50555555555553" r="4" fill="#FFC107" class="point" /><circle cx="330" cy="309.7833333333333" r="4" fill="#FFC107" class="point" /><circle cx="470" cy="300.01666666666665" r="4" fill="#FFC107" class="point" /><circle cx="610" cy="280.0333333333333" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="271.06111111111113" r="4" fill="#FFC107" class="point" /><polyline points="50,337.86111111111114 190,324.1611111111111 330,346.6722222222222 470,340.9111111111111 610,334.2055555555556 750,330.7388888888889" class="line" stroke="#FF5722" /><circle cx="50" cy="337.86111111111114" r="4" fill="#FF5722" class="point" /><circle cx="190" cy="324.1611111111111" r="4" fill="#FF5722" class="point" /><circle cx="330" cy="346.6722222222222" r="4" fill="#FF5722" class="point" /><circle cx="470" cy="340.9111111111111" r="4" fill="#FF5722" class="point" /><circle cx="610" cy="334.2055555555556" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="330.7388888888889" r="4" fill="#FF5722" class="point" /><line x1="55" y1="50" x2="75" y2="50" class="line dashed" stroke="#4CAF50" /><text x="115" y="54" class="label" text-anchor="start">pull(JIT)</text><line x1="55" y1="70" x2="75" y2="70" class="line dashed" stroke="#2196F3" /><text x="115" y="74" class="label" text-anchor="start">stream(JIT)</text><line x1="55" y1="90" x2="75" y2="90" class="line dashed" stroke="#FFC107" /><text x="115" y="94" class="label" text-anchor="start">sax2(JIT)</text><line x1="55" y1="110" x2="75" y2="110" class="line dashed" stroke="#FF5722" /><text x="115" y="114" class="label" text-anchor="start">dom(JIT)</text><line x1="55" y1="130" x2="75" y2="130" class="line" stroke="#4CAF50" /><text x="115" y="134" class="label" text-anchor="start">pull</text><line x1="55" y1="150" x2="75" y2="150" class="line" stroke="#2196F3" /><text x="115" y="154" class="label" text-anchor="start">stream</text><line x1="55" y1="170" x2="75" y2="170" class="line" stroke="#FFC107" /><text x="115" y="174" class="label" text-anchor="start">sax2</text><line x1="55" y1="190" x2="75" y2="190" class="line" stroke="#FF5722" /><text x="115" y="194" class="label" text-anchor="start">dom</text></svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="400">
|
2
|
+
<style>
|
3
|
+
.line { fill: none; stroke-width: 2; }
|
4
|
+
.dashed { stroke-dasharray: 5, 5; }
|
5
|
+
.label { font-size: 18px; text-anchor: middle; }
|
6
|
+
.axis { stroke: #000; stroke-width: 1; }
|
7
|
+
.grid { stroke: #ccc; stroke-width: 0.5; }
|
8
|
+
.point { fill-opacity: 0.8; }
|
9
|
+
.title { font-size: 22px; font-weight: bold; text-anchor: middle; }
|
10
|
+
</style>
|
11
|
+
<!-- 軸 -->
|
12
|
+
<line x1="50" y1="350" x2="750" y2="350" class="axis" />
|
13
|
+
<line x1="50" y1="50" x2="50" y2="350" class="axis" />
|
14
|
+
<!-- タイトル -->
|
15
|
+
<text x="400" y="25" class="title">REXML Performance benchmarks</text>
|
16
|
+
<text x="400" y="388" class="label">rexml version</text>
|
17
|
+
<text x="12" y="200" class="label" transform="rotate(-90, 12, 200)">i/s</text>
|
18
|
+
<line x1="50" y1="350.0" x2="750" y2="350.0" class="grid" /><text x="30" y="355.0" class="label" text-anchor="end">18.0</text><line x1="50" y1="275.0" x2="750" y2="275.0" class="grid" /><text x="30" y="280.0" class="label" text-anchor="end">22.0</text><line x1="50" y1="200.0" x2="750" y2="200.0" class="grid" /><text x="30" y="205.0" class="label" text-anchor="end">26.0</text><line x1="50" y1="125.0" x2="750" y2="125.0" class="grid" /><text x="30" y="130.0" class="label" text-anchor="end">30.0</text><line x1="50" y1="50.0" x2="750" y2="50.0" class="grid" /><text x="30" y="55.0" class="label" text-anchor="end">34.0</text><line x1="50" y1="50" x2="50" y2="350" class="grid" /><text x="50" y="370" class="label">3.2.6</text><line x1="750" y1="50" x2="750" y2="350" class="grid" /><text x="750" y="370" class="label">3.4.0</text><polyline points="50,126.10625000000002 750,67.19375000000002" class="line" stroke="#4CAF50" /><circle cx="50" cy="126.10625000000002" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="67.19375000000002" r="4" fill="#4CAF50" class="point" /><polyline points="50,160.41875 750,75.76250000000005" class="line" stroke="#2196F3" /><circle cx="50" cy="160.41875" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="75.76250000000005" r="4" fill="#2196F3" class="point" /><polyline points="50,203.35624999999996 750,151.36249999999998" class="line" stroke="#FFC107" /><circle cx="50" cy="203.35624999999996" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="151.36249999999998" r="4" fill="#FFC107" class="point" /><polyline points="50,346.53125 750,334.19375" class="line" stroke="#FF5722" /><circle cx="50" cy="346.53125" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="334.19375" r="4" fill="#FF5722" class="point" /><line x1="55" y1="50" x2="75" y2="50" class="line" stroke="#4CAF50" /><text x="115" y="54" class="label" text-anchor="start">pull</text><line x1="55" y1="70" x2="75" y2="70" class="line" stroke="#2196F3" /><text x="115" y="74" class="label" text-anchor="start">stream</text><line x1="55" y1="90" x2="75" y2="90" class="line" stroke="#FFC107" /><text x="115" y="94" class="label" text-anchor="start">sax2</text><line x1="55" y1="110" x2="75" y2="110" class="line" stroke="#FF5722" /><text x="115" y="114" class="label" text-anchor="start">dom</text></svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="400">
|
2
|
+
<style>
|
3
|
+
.line { fill: none; stroke-width: 2; }
|
4
|
+
.dashed { stroke-dasharray: 5, 5; }
|
5
|
+
.label { font-size: 18px; text-anchor: middle; }
|
6
|
+
.axis { stroke: #000; stroke-width: 1; }
|
7
|
+
.grid { stroke: #ccc; stroke-width: 0.5; }
|
8
|
+
.point { fill-opacity: 0.8; }
|
9
|
+
.title { font-size: 22px; font-weight: bold; text-anchor: middle; }
|
10
|
+
</style>
|
11
|
+
<!-- 軸 -->
|
12
|
+
<line x1="50" y1="350" x2="750" y2="350" class="axis" />
|
13
|
+
<line x1="50" y1="50" x2="50" y2="350" class="axis" />
|
14
|
+
<!-- タイトル -->
|
15
|
+
<text x="400" y="25" class="title">REXML Performance benchmarks</text>
|
16
|
+
<text x="400" y="388" class="label">rexml version</text>
|
17
|
+
<text x="12" y="200" class="label" transform="rotate(-90, 12, 200)">i/s</text>
|
18
|
+
<line x1="50" y1="350.0" x2="750" y2="350.0" class="grid" /><text x="30" y="355.0" class="label" text-anchor="end">25.0</text><line x1="50" y1="290.0" x2="750" y2="290.0" class="grid" /><text x="30" y="295.0" class="label" text-anchor="end">32.0</text><line x1="50" y1="230.0" x2="750" y2="230.0" class="grid" /><text x="30" y="235.0" class="label" text-anchor="end">39.0</text><line x1="50" y1="170.0" x2="750" y2="170.0" class="grid" /><text x="30" y="175.0" class="label" text-anchor="end">46.0</text><line x1="50" y1="110.0" x2="750" y2="110.0" class="grid" /><text x="30" y="115.0" class="label" text-anchor="end">53.0</text><line x1="50" y1="50.0" x2="750" y2="50.0" class="grid" /><text x="30" y="55.0" class="label" text-anchor="end">60.0</text><line x1="50" y1="50" x2="50" y2="350" class="grid" /><text x="50" y="370" class="label">3.2.6</text><line x1="750" y1="50" x2="750" y2="350" class="grid" /><text x="750" y="370" class="label">3.4.0</text><polyline points="50,198.1914285714286 750,51.01999999999998" class="line dashed" stroke="#4CAF50" /><circle cx="50" cy="198.1914285714286" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="51.01999999999998" r="4" fill="#4CAF50" class="point" /><polyline points="50,229.7942857142857 750,73.57142857142861" class="line dashed" stroke="#2196F3" /><circle cx="50" cy="229.7942857142857" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="73.57142857142861" r="4" fill="#2196F3" class="point" /><polyline points="50,250.83714285714285 750,130.04000000000002" class="line dashed" stroke="#FFC107" /><circle cx="50" cy="250.83714285714285" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="130.04000000000002" r="4" fill="#FFC107" class="point" /><polyline points="50,342.32 750,293.6085714285714" class="line dashed" stroke="#FF5722" /><circle cx="50" cy="342.32" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="293.6085714285714" r="4" fill="#FF5722" class="point" /><line x1="55" y1="50" x2="75" y2="50" class="line dashed" stroke="#4CAF50" /><text x="115" y="54" class="label" text-anchor="start">pull(JIT)</text><line x1="55" y1="70" x2="75" y2="70" class="line dashed" stroke="#2196F3" /><text x="115" y="74" class="label" text-anchor="start">stream(JIT)</text><line x1="55" y1="90" x2="75" y2="90" class="line dashed" stroke="#FFC107" /><text x="115" y="94" class="label" text-anchor="start">sax2(JIT)</text><line x1="55" y1="110" x2="75" y2="110" class="line dashed" stroke="#FF5722" /><text x="115" y="114" class="label" text-anchor="start">dom(JIT)</text></svg>
|
data/images/svg_341.svg
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="400">
|
2
|
+
<style>
|
3
|
+
.line { fill: none; stroke-width: 2; }
|
4
|
+
.dashed { stroke-dasharray: 5, 5; }
|
5
|
+
.label { font-size: 18px; text-anchor: middle; }
|
6
|
+
.axis { stroke: #000; stroke-width: 1; }
|
7
|
+
.grid { stroke: #ccc; stroke-width: 0.5; }
|
8
|
+
.point { fill-opacity: 0.8; }
|
9
|
+
.title { font-size: 22px; font-weight: bold; text-anchor: middle; }
|
10
|
+
</style>
|
11
|
+
<!-- 軸 -->
|
12
|
+
<line x1="50" y1="350" x2="750" y2="350" class="axis" />
|
13
|
+
<line x1="50" y1="50" x2="50" y2="350" class="axis" />
|
14
|
+
<!-- タイトル -->
|
15
|
+
<text x="400" y="25" class="title">REXML Performance benchmarks</text>
|
16
|
+
<text x="400" y="388" class="label">rexml version</text>
|
17
|
+
<text x="12" y="200" class="label" transform="rotate(-90, 12, 200)">i/s</text>
|
18
|
+
<line x1="50" y1="350.0" x2="750" y2="350.0" class="grid" /><text x="30" y="355.0" class="label" text-anchor="end">18.0</text><line x1="50" y1="287.5" x2="750" y2="287.5" class="grid" /><text x="30" y="292.5" class="label" text-anchor="end">28.0</text><line x1="50" y1="225.0" x2="750" y2="225.0" class="grid" /><text x="30" y="230.0" class="label" text-anchor="end">38.0</text><line x1="50" y1="162.5" x2="750" y2="162.5" class="grid" /><text x="30" y="167.5" class="label" text-anchor="end">48.0</text><line x1="50" y1="100.0" x2="750" y2="100.0" class="grid" /><text x="30" y="105.0" class="label" text-anchor="end">58.0</text><line x1="50" y1="50" x2="50" y2="350" class="grid" /><text x="50" y="370" class="label">3.2.6</text><line x1="400" y1="50" x2="400" y2="350" class="grid" /><text x="400" y="370" class="label">3.4.0</text><line x1="750" y1="50" x2="750" y2="350" class="grid" /><text x="750" y="370" class="label">3.4.1</text><polyline points="50,195.55625 400,88.24375000000003 750,50.67500000000001" class="line dashed" stroke="#4CAF50" /><circle cx="50" cy="195.55625" r="4" fill="#4CAF50" class="point" /><circle cx="400" cy="88.24375000000003" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="50.67500000000001" r="4" fill="#4CAF50" class="point" /><polyline points="50,218.6 400,104.6875 750,75.81875000000002" class="line dashed" stroke="#2196F3" /><circle cx="50" cy="218.6" r="4" fill="#2196F3" class="point" /><circle cx="400" cy="104.6875" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="75.81875000000002" r="4" fill="#2196F3" class="point" /><polyline points="50,233.94374999999997 400,145.8625 750,130.15625" class="line dashed" stroke="#FFC107" /><circle cx="50" cy="233.94374999999997" r="4" fill="#FFC107" class="point" /><circle cx="400" cy="145.8625" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="130.15625" r="4" fill="#FFC107" class="point" /><polyline points="50,300.65 400,265.13125 750,250.45000000000002" class="line dashed" stroke="#FF5722" /><circle cx="50" cy="300.65" r="4" fill="#FF5722" class="point" /><circle cx="400" cy="265.13125" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="250.45000000000002" r="4" fill="#FF5722" class="point" /><polyline points="50,275.36875 400,255.73125000000002 750,247.7125" class="line" stroke="#4CAF50" /><circle cx="50" cy="275.36875" r="4" fill="#4CAF50" class="point" /><circle cx="400" cy="255.73125000000002" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="247.7125" r="4" fill="#4CAF50" class="point" /><polyline points="50,286.80625 400,258.5875 750,248.4375" class="line" stroke="#2196F3" /><circle cx="50" cy="286.80625" r="4" fill="#2196F3" class="point" /><circle cx="400" cy="258.5875" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="248.4375" r="4" fill="#2196F3" class="point" /><polyline points="50,301.11875 400,283.7875 750,273.69375" class="line" stroke="#FFC107" /><circle cx="50" cy="301.11875" r="4" fill="#FFC107" class="point" /><circle cx="400" cy="283.7875" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="273.69375" r="4" fill="#FFC107" class="point" /><polyline points="50,348.84375 400,344.73125 750,340.83125" class="line" stroke="#FF5722" /><circle cx="50" cy="348.84375" r="4" fill="#FF5722" class="point" /><circle cx="400" cy="344.73125" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="340.83125" r="4" fill="#FF5722" class="point" /><line x1="55" y1="50" x2="75" y2="50" class="line dashed" stroke="#4CAF50" /><text x="115" y="54" class="label" text-anchor="start">pull(JIT)</text><line x1="55" y1="70" x2="75" y2="70" class="line dashed" stroke="#2196F3" /><text x="115" y="74" class="label" text-anchor="start">stream(JIT)</text><line x1="55" y1="90" x2="75" y2="90" class="line dashed" stroke="#FFC107" /><text x="115" y="94" class="label" text-anchor="start">sax2(JIT)</text><line x1="55" y1="110" x2="75" y2="110" class="line dashed" stroke="#FF5722" /><text x="115" y="114" class="label" text-anchor="start">dom(JIT)</text><line x1="55" y1="130" x2="75" y2="130" class="line" stroke="#4CAF50" /><text x="115" y="134" class="label" text-anchor="start">pull</text><line x1="55" y1="150" x2="75" y2="150" class="line" stroke="#2196F3" /><text x="115" y="154" class="label" text-anchor="start">stream</text><line x1="55" y1="170" x2="75" y2="170" class="line" stroke="#FFC107" /><text x="115" y="174" class="label" text-anchor="start">sax2</text><line x1="55" y1="190" x2="75" y2="190" class="line" stroke="#FF5722" /><text x="115" y="194" class="label" text-anchor="start">dom</text></svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="400">
|
2
|
+
<style>
|
3
|
+
.line { fill: none; stroke-width: 2; }
|
4
|
+
.dashed { stroke-dasharray: 5, 5; }
|
5
|
+
.label { font-size: 18px; text-anchor: middle; }
|
6
|
+
.axis { stroke: #000; stroke-width: 1; }
|
7
|
+
.grid { stroke: #ccc; stroke-width: 0.5; }
|
8
|
+
.point { fill-opacity: 0.8; }
|
9
|
+
.title { font-size: 22px; font-weight: bold; text-anchor: middle; }
|
10
|
+
</style>
|
11
|
+
<!-- 軸 -->
|
12
|
+
<line x1="50" y1="350" x2="750" y2="350" class="axis" />
|
13
|
+
<line x1="50" y1="50" x2="50" y2="350" class="axis" />
|
14
|
+
<!-- タイトル -->
|
15
|
+
<text x="400" y="25" class="title">REXML Performance benchmarks</text>
|
16
|
+
<text x="400" y="388" class="label">rexml version</text>
|
17
|
+
<text x="12" y="200" class="label" transform="rotate(-90, 12, 200)">i/s</text>
|
18
|
+
<line x1="50" y1="350.0" x2="750" y2="350.0" class="grid" /><text x="30" y="355.0" class="label" text-anchor="end">18.0</text><line x1="50" y1="279.4117647058823" x2="750" y2="279.4117647058823" class="grid" /><text x="30" y="284.4117647058823" class="label" text-anchor="end">22.0</text><line x1="50" y1="208.8235294117647" x2="750" y2="208.8235294117647" class="grid" /><text x="30" y="213.8235294117647" class="label" text-anchor="end">26.0</text><line x1="50" y1="138.23529411764704" x2="750" y2="138.23529411764704" class="grid" /><text x="30" y="143.23529411764704" class="label" text-anchor="end">30.0</text><line x1="50" y1="67.64705882352939" x2="750" y2="67.64705882352939" class="grid" /><text x="30" y="72.64705882352939" class="label" text-anchor="end">34.0</text><line x1="50" y1="50" x2="50" y2="350" class="grid" /><text x="50" y="370" class="label">3.2.6</text><line x1="400" y1="50" x2="400" y2="350" class="grid" /><text x="400" y="370" class="label">3.4.0</text><line x1="750" y1="50" x2="750" y2="350" class="grid" /><text x="750" y="370" class="label">3.4.1</text><polyline points="50,139.27647058823533 400,83.82941176470592 750,61.188235294117646" class="line" stroke="#4CAF50" /><circle cx="50" cy="139.27647058823533" r="4" fill="#4CAF50" class="point" /><circle cx="400" cy="83.82941176470592" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="61.188235294117646" r="4" fill="#4CAF50" class="point" /><polyline points="50,171.5705882352941 400,91.89411764705886 750,63.23529411764707" class="line" stroke="#2196F3" /><circle cx="50" cy="171.5705882352941" r="4" fill="#2196F3" class="point" /><circle cx="400" cy="91.89411764705886" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="63.23529411764707" r="4" fill="#2196F3" class="point" /><polyline points="50,211.98235294117643 400,163.0470588235294 750,134.5470588235294" class="line" stroke="#FFC107" /><circle cx="50" cy="211.98235294117643" r="4" fill="#FFC107" class="point" /><circle cx="400" cy="163.0470588235294" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="134.5470588235294" r="4" fill="#FFC107" class="point" /><polyline points="50,346.7352941176471 400,335.1235294117647 750,324.11176470588236" class="line" stroke="#FF5722" /><circle cx="50" cy="346.7352941176471" r="4" fill="#FF5722" class="point" /><circle cx="400" cy="335.1235294117647" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="324.11176470588236" r="4" fill="#FF5722" class="point" /><line x1="55" y1="50" x2="75" y2="50" class="line" stroke="#4CAF50" /><text x="115" y="54" class="label" text-anchor="start">pull</text><line x1="55" y1="70" x2="75" y2="70" class="line" stroke="#2196F3" /><text x="115" y="74" class="label" text-anchor="start">stream</text><line x1="55" y1="90" x2="75" y2="90" class="line" stroke="#FFC107" /><text x="115" y="94" class="label" text-anchor="start">sax2</text><line x1="55" y1="110" x2="75" y2="110" class="line" stroke="#FF5722" /><text x="115" y="114" class="label" text-anchor="start">dom</text></svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="400">
|
2
|
+
<style>
|
3
|
+
.line { fill: none; stroke-width: 2; }
|
4
|
+
.dashed { stroke-dasharray: 5, 5; }
|
5
|
+
.label { font-size: 18px; text-anchor: middle; }
|
6
|
+
.axis { stroke: #000; stroke-width: 1; }
|
7
|
+
.grid { stroke: #ccc; stroke-width: 0.5; }
|
8
|
+
.point { fill-opacity: 0.8; }
|
9
|
+
.title { font-size: 22px; font-weight: bold; text-anchor: middle; }
|
10
|
+
</style>
|
11
|
+
<!-- 軸 -->
|
12
|
+
<line x1="50" y1="350" x2="750" y2="350" class="axis" />
|
13
|
+
<line x1="50" y1="50" x2="50" y2="350" class="axis" />
|
14
|
+
<!-- タイトル -->
|
15
|
+
<text x="400" y="25" class="title">REXML Performance benchmarks</text>
|
16
|
+
<text x="400" y="388" class="label">rexml version</text>
|
17
|
+
<text x="12" y="200" class="label" transform="rotate(-90, 12, 200)">i/s</text>
|
18
|
+
<line x1="50" y1="350.0" x2="750" y2="350.0" class="grid" /><text x="30" y="355.0" class="label" text-anchor="end">25.0</text><line x1="50" y1="284.1463414634146" x2="750" y2="284.1463414634146" class="grid" /><text x="30" y="289.1463414634146" class="label" text-anchor="end">34.0</text><line x1="50" y1="218.29268292682926" x2="750" y2="218.29268292682926" class="grid" /><text x="30" y="223.29268292682926" class="label" text-anchor="end">43.0</text><line x1="50" y1="152.4390243902439" x2="750" y2="152.4390243902439" class="grid" /><text x="30" y="157.4390243902439" class="label" text-anchor="end">52.0</text><line x1="50" y1="86.58536585365852" x2="750" y2="86.58536585365852" class="grid" /><text x="30" y="91.58536585365852" class="label" text-anchor="end">61.0</text><line x1="50" y1="50" x2="50" y2="350" class="grid" /><text x="50" y="370" class="label">3.2.6</text><line x1="400" y1="50" x2="400" y2="350" class="grid" /><text x="400" y="370" class="label">3.4.0</text><line x1="750" y1="50" x2="750" y2="350" class="grid" /><text x="750" y="370" class="label">3.4.1</text><polyline points="50,220.40731707317076 400,94.77317073170732 750,50.790243902439045" class="line dashed" stroke="#4CAF50" /><circle cx="50" cy="220.40731707317076" r="4" fill="#4CAF50" class="point" /><circle cx="400" cy="94.77317073170732" r="4" fill="#4CAF50" class="point" /><circle cx="750" cy="50.790243902439045" r="4" fill="#4CAF50" class="point" /><polyline points="50,247.38536585365853 400,114.02439024390242 750,80.2268292682927" class="line dashed" stroke="#2196F3" /><circle cx="50" cy="247.38536585365853" r="4" fill="#2196F3" class="point" /><circle cx="400" cy="114.02439024390242" r="4" fill="#2196F3" class="point" /><circle cx="750" cy="80.2268292682927" r="4" fill="#2196F3" class="point" /><polyline points="50,265.34878048780485 400,162.22926829268292 750,143.84146341463418" class="line dashed" stroke="#FFC107" /><circle cx="50" cy="265.34878048780485" r="4" fill="#FFC107" class="point" /><circle cx="400" cy="162.22926829268292" r="4" fill="#FFC107" class="point" /><circle cx="750" cy="143.84146341463418" r="4" fill="#FFC107" class="point" /><polyline points="50,343.4439024390244 400,301.8609756097561 750,284.67317073170733" class="line dashed" stroke="#FF5722" /><circle cx="50" cy="343.4439024390244" r="4" fill="#FF5722" class="point" /><circle cx="400" cy="301.8609756097561" r="4" fill="#FF5722" class="point" /><circle cx="750" cy="284.67317073170733" r="4" fill="#FF5722" class="point" /><line x1="55" y1="50" x2="75" y2="50" class="line dashed" stroke="#4CAF50" /><text x="115" y="54" class="label" text-anchor="start">pull(JIT)</text><line x1="55" y1="70" x2="75" y2="70" class="line dashed" stroke="#2196F3" /><text x="115" y="74" class="label" text-anchor="start">stream(JIT)</text><line x1="55" y1="90" x2="75" y2="90" class="line dashed" stroke="#FFC107" /><text x="115" y="94" class="label" text-anchor="start">sax2(JIT)</text><line x1="55" y1="110" x2="75" y2="110" class="line dashed" stroke="#FF5722" /><text x="115" y="114" class="label" text-anchor="start">dom(JIT)</text></svg>
|
Binary file
|
data/rubykaigi-2025.rab
ADDED
@@ -0,0 +1,905 @@
|
|
1
|
+
= Improvement of REXML and speed up using StringScanner
|
2
|
+
|
3
|
+
: author
|
4
|
+
NAITOH Jun
|
5
|
+
: institution
|
6
|
+
MedPeer, Inc.
|
7
|
+
: content-source
|
8
|
+
RubyKaigi 2025
|
9
|
+
: date
|
10
|
+
2025-04-17
|
11
|
+
: theme
|
12
|
+
.
|
13
|
+
|
14
|
+
|
15
|
+
: start-time
|
16
|
+
2025-04-17T11:50:00+09:00
|
17
|
+
: end-time
|
18
|
+
2025-04-17T12:20:00+09:00
|
19
|
+
|
20
|
+
== Slide properties
|
21
|
+
|
22
|
+
: enable-title-on-image
|
23
|
+
false
|
24
|
+
|
25
|
+
= NAITOH Jun
|
26
|
+
|
27
|
+
* @naitoh (GitHub and X(Twitter))\n
|
28
|
+
(('note:GitHub と X(Twitter) のアカウント'))
|
29
|
+
* A new maintainer of the (({rexml})) library\n
|
30
|
+
(('note:(({rexml}))ライブラリーの新メンテナー 🆕'))
|
31
|
+
* ((<Red Data Tools|URL:https://red-data-tools.github.io/>)) project member\n
|
32
|
+
(('note:Red Data Toolsプロジェクトのメンバー'))
|
33
|
+
* ((<redmine.tokyo|URL:https://redmine.tokyo/>)) stuff\n
|
34
|
+
(('note:redmine.tokyo 勉強会のスタッフ'))
|
35
|
+
* Working at MedPeer, Inc.\n
|
36
|
+
(('note:MedPeerで働いている'))
|
37
|
+
|
38
|
+
= (('note:MedPeer'))
|
39
|
+
|
40
|
+
# img
|
41
|
+
# src = images/medpeer_mission.png
|
42
|
+
# relative_height = 70
|
43
|
+
|
44
|
+
== Slide properties
|
45
|
+
|
46
|
+
: enable-title-on-image
|
47
|
+
false
|
48
|
+
|
49
|
+
|
50
|
+
= (('note: '))
|
51
|
+
|
52
|
+
# img
|
53
|
+
# src = images/medpeer.png
|
54
|
+
# relative_height = 100
|
55
|
+
|
56
|
+
== Slide properties
|
57
|
+
|
58
|
+
: enable-title-on-image
|
59
|
+
false
|
60
|
+
|
61
|
+
= rexml in Ruby 3.4 (1)\n(('note:Ruby 3.4の rexml(1)'))
|
62
|
+
|
63
|
+
* Faster XML parsing\n(('note:XMLパースの高速化'))
|
64
|
+
* It is up to ((*50%*)) faster between\n
|
65
|
+
rexml 3.2.6(attached to Ruby 3.3.0) and\n
|
66
|
+
rexml 3.4.0(attached to Ruby 3.4.0). \n
|
67
|
+
(('note:rexml 3.2.6(Ruby 3.3.0添付)とrexml 3.4.0(Ruby 3.4.0添付)の間で、((*最大50%*))速くなった。'))
|
68
|
+
|
69
|
+
= Benchmark target file
|
70
|
+
|
71
|
+
<?xml version="1.0"?>
|
72
|
+
<root>
|
73
|
+
<child id0="0" id1="0" />
|
74
|
+
:
|
75
|
+
<child id0="4999" id1="4999" />
|
76
|
+
</root>
|
77
|
+
|
78
|
+
(('tag:center'))
|
79
|
+
Parsing XML with 5000 child nodes.\n(('note:5000個の子ノードを持つXMLをパースする'))
|
80
|
+
|
81
|
+
|
82
|
+
= Ruby 3.4 YJIT disable(('note: YJIT 無効'))
|
83
|
+
|
84
|
+
# img
|
85
|
+
# src = images/svg_340_jit_disable.svg
|
86
|
+
# relative_height = 60
|
87
|
+
|
88
|
+
# RT
|
89
|
+
|
90
|
+
(('tag:small'))parser, (('tag:small'))3.2.6, (('tag:small'))3.4.0, (('tag:small'))Faster?
|
91
|
+
|
92
|
+
(('tag:center'))(('tag:small'))dom, (('tag:small'))(('tag:center'))18.19 i/s, (('tag:small'))(('tag:center'))18.84 i/s, (('tag:small'))(('tag:center'))1.03x
|
93
|
+
(('tag:center'))(('tag:small'))sax2, (('tag:small'))(('tag:center'))25.82 i/s, (('tag:small'))(('tag:center'))28.59 i/s, (('tag:small'))(('tag:center'))1.11x
|
94
|
+
(('tag:center'))(('tag:small'))pull, (('tag:small'))(('tag:center'))29.94 i/s, (('tag:small'))(('tag:center'))33.08 i/s, (('tag:small'))(('tag:center'))1.10x
|
95
|
+
(('tag:center'))(('tag:small'))stream, (('tag:small'))(('tag:center'))28.11 i/s, (('tag:small'))(('tag:center'))32.62 i/s, (('tag:small'))(('tag:center'))1.16x
|
96
|
+
|
97
|
+
= Ruby 3.4 YJIT enable(('note: YJIT 有効'))
|
98
|
+
|
99
|
+
# img
|
100
|
+
# src = images/svg_340_jit_enable.svg
|
101
|
+
# relative_height = 60
|
102
|
+
|
103
|
+
# RT
|
104
|
+
|
105
|
+
(('tag:small'))parser, (('tag:small'))3.2.6, (('tag:small'))3.4.0, (('tag:small'))Faster?
|
106
|
+
|
107
|
+
(('tag:center'))(('tag:small'))dom, (('tag:small'))(('tag:center'))25.90 i/s, (('tag:small'))(('tag:center'))31.58 i/s, (('tag:small'))(('tag:center'))1.22x
|
108
|
+
(('tag:center'))(('tag:small'))sax2, (('tag:small'))(('tag:center'))36.57 i/s, (('tag:small'))(('tag:center'))50.67 i/s, (('tag:small'))(('tag:center'))1.39x
|
109
|
+
(('tag:center'))(('tag:small'))pull, (('tag:small'))(('tag:center'))42.71 i/s, (('tag:small'))(('tag:center'))59.88 i/s, (('tag:small'))(('tag:center'))1.40x
|
110
|
+
(('tag:center'))(('tag:small'))stream, (('tag:small'))(('tag:center'))39.02 i/s, (('tag:small'))(('tag:center'))57.25 i/s, (('tag:small'))(('tag:center'))((*1.47x*))
|
111
|
+
|
112
|
+
= rexml in Ruby 3.4 (2)\n(('note:Ruby 3.4の rexml(2)'))
|
113
|
+
|
114
|
+
* Faster XML parsing\n(('note:XMLパースの高速化'))
|
115
|
+
* It is up to ((*60%*)) faster between\n
|
116
|
+
rexml 3.2.6(attached to Ruby 3.3.0) and rexml 3.4.1. \n
|
117
|
+
(('note:rexml 3.2.6(Ruby 3.3.0添付)とrexml 3.4.1の間で、((*最大60%*))速くなった'))
|
118
|
+
|
119
|
+
= Ruby 3.4 YJIT disable(('note: YJIT 無効'))
|
120
|
+
|
121
|
+
# img
|
122
|
+
# src = images/svg_341_jit_disable.svg
|
123
|
+
# relative_height = 60
|
124
|
+
|
125
|
+
# RT
|
126
|
+
|
127
|
+
(('tag:small'))parser, (('tag:small'))3.2.6, (('tag:small'))3.4.0, (('tag:small'))3.4.1, (('tag:small'))Faster?
|
128
|
+
|
129
|
+
(('tag:center'))(('tag:small'))dom, (('tag:small'))(('tag:center'))18.19 i/s, (('tag:small'))(('tag:center'))18.84 i/s, (('tag:small'))(('tag:center'))19.47 i/s, (('tag:small'))(('tag:center'))1.07x
|
130
|
+
(('tag:center'))(('tag:small'))sax2, (('tag:small'))(('tag:center'))25.82 i/s, (('tag:small'))(('tag:center'))28.59 i/s, (('tag:small'))(('tag:center'))30.21 i/s, (('tag:small'))(('tag:center'))1.16x
|
131
|
+
(('tag:center'))(('tag:small'))pull, (('tag:small'))(('tag:center'))29.94 i/s, (('tag:small'))(('tag:center'))33.08 i/s, (('tag:small'))(('tag:center'))34.37 i/s, (('tag:small'))(('tag:center'))1.14x
|
132
|
+
(('tag:center'))(('tag:small'))stream, (('tag:small'))(('tag:center'))28.11 i/s, (('tag:small'))(('tag:center'))32.62 i/s, (('tag:small'))(('tag:center'))34.25 i/s, (('tag:small'))(('tag:center'))1.21x
|
133
|
+
|
134
|
+
= Ruby 3.4 YJIT enable(('note: YJIT 有効'))
|
135
|
+
|
136
|
+
# img
|
137
|
+
# src = images/svg_341_jit_enable.svg
|
138
|
+
# relative_height = 60
|
139
|
+
|
140
|
+
# RT
|
141
|
+
|
142
|
+
(('tag:small'))parser, (('tag:small'))3.2.6, (('tag:small'))3.4.0, (('tag:small'))3.4.1, (('tag:small'))Faster?
|
143
|
+
|
144
|
+
(('tag:center'))(('tag:small'))dom, (('tag:small'))(('tag:center'))25.90 i/s, (('tag:small'))(('tag:center'))31.58 i/s, (('tag:small'))(('tag:center'))33.93 i/s, (('tag:small'))(('tag:center'))1.31x
|
145
|
+
(('tag:center'))(('tag:small'))sax2, (('tag:small'))(('tag:center'))36.57 i/s, (('tag:small'))(('tag:center'))50.67 i/s, (('tag:small'))(('tag:center'))53.18 i/s, (('tag:small'))(('tag:center'))1.45x
|
146
|
+
(('tag:center'))(('tag:small'))pull, (('tag:small'))(('tag:center'))42.71 i/s, (('tag:small'))(('tag:center'))59.88 i/s, (('tag:small'))(('tag:center'))65.89 i/s, (('tag:small'))(('tag:center'))1.54x
|
147
|
+
(('tag:center'))(('tag:small'))stream, (('tag:small'))(('tag:center'))39.02 i/s, (('tag:small'))(('tag:center'))57.25 i/s, (('tag:small'))(('tag:center'))61.87 i/s, (('tag:small'))(('tag:center'))((*1.58x*))
|
148
|
+
|
149
|
+
= Ruby 3.4 rexml 3.4.1
|
150
|
+
|
151
|
+
# img
|
152
|
+
# src = images/svg_341.svg
|
153
|
+
# relative_height = 80
|
154
|
+
|
155
|
+
(('tag:center'))
|
156
|
+
Up to ((*60%*)) faster.\n
|
157
|
+
(('note:((*最大60%*))高速化'))
|
158
|
+
|
159
|
+
= RubyKaigi 2024 LT
|
160
|
+
|
161
|
+
# img
|
162
|
+
# src = images/RubyKaigi2024LT.png
|
163
|
+
# relative_height = 60
|
164
|
+
|
165
|
+
* Up to 60% faster since rexml 3.2.6.\n
|
166
|
+
(('note:rexml 3.2.6から最大((*60%*))速くなった。'))
|
167
|
+
(('tag:center'))(('wait'))🤔
|
168
|
+
|
169
|
+
= The release version 3.2.7 was slowing down.\n(('note:リリース版の3.2.7が遅くなっていた。'))
|
170
|
+
|
171
|
+
# img
|
172
|
+
# src = images/rexml_x_1797256482272235856.png
|
173
|
+
# relative_height = 100
|
174
|
+
|
175
|
+
== Slide properties
|
176
|
+
|
177
|
+
: enable-title-on-image
|
178
|
+
false
|
179
|
+
|
180
|
+
= Ruby 3.4 rexml 3.2.7
|
181
|
+
|
182
|
+
# img
|
183
|
+
# src = images/svg_327.svg
|
184
|
+
# relative_height = 80
|
185
|
+
|
186
|
+
(('tag:center'))
|
187
|
+
It was slow in rexml 3.2.7.\n
|
188
|
+
(('note:rexml 3.2.7 で遅くなっていた'))
|
189
|
+
|
190
|
+
|
191
|
+
= Parsing process was slowing down to deal with CVE.\n(('note:CVEに対処するためパース処理が遅くなっていた'))
|
192
|
+
|
193
|
+
# img
|
194
|
+
# src = images/CVE-2024-35176.png
|
195
|
+
# relative_height = 80
|
196
|
+
|
197
|
+
(('tag:center'))
|
198
|
+
(('tag:small'))
|
199
|
+
((<CVE-2024-35176: DoS vulnerability in REXML|URL:https://www.ruby-lang.org/en/news/2024/05/16/dos-rexml-cve-2024-35176/>))
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
= Make REXML ((*Fast Again*)).\n(('note:REXML を((*再び高速化*))する'))
|
204
|
+
|
205
|
+
= What's REXML\n(('note:REXML とは?'))
|
206
|
+
|
207
|
+
* REXML is a standard XML library (Bundled Gem) for Ruby implemented in Pure Ruby.\n
|
208
|
+
(('note:REXMLはPure Rubyで実装されたRuby用の標準XMLライブラリ(Bundled Gem)'))
|
209
|
+
|
210
|
+
= What's XML?\n(('note:XML とは?'))
|
211
|
+
|
212
|
+
# rouge xml
|
213
|
+
|
214
|
+
<?xml version="1.0"?>
|
215
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
216
|
+
<rect x="0" y="0" width="100" height="60" fill="#ddd" />
|
217
|
+
<polygon points="50 10, 70 30, 50 50, 30 30" fill="#99f" />
|
218
|
+
</svg>
|
219
|
+
|
220
|
+
* Describe using tags like HTML.\n
|
221
|
+
(('note:HTML の様にタグを用いて記述する'))
|
222
|
+
* Highly scalable data exchange format.\n
|
223
|
+
(('note:拡張性の高いデータ交換用フォーマット'))
|
224
|
+
|
225
|
+
= XML-based format example\n(('note:XMLベースのフォーマット例'))
|
226
|
+
|
227
|
+
* SVG, DOCX, XLSX, MathML, PubMed-XML, CIM-XML, etc.\n
|
228
|
+
(('note:SVG, DOCX, XLSX、MathML、PubMed XML, CIM-XML, ..'))
|
229
|
+
* Complex expressions are possible.\n
|
230
|
+
(('note:複雑な表現が可能'))
|
231
|
+
|
232
|
+
= XML character encoding.\n(('note:XML の 文字コード'))
|
233
|
+
|
234
|
+
* XML supports UTF-8 and UTF-16 (required). \n
|
235
|
+
(('note:XML は UTF-8 と UTF-16 をサポート(必須)'))
|
236
|
+
* Other character encoding can be used by declaring XML encoding (optional).\n
|
237
|
+
(('note:XMLエンコーディングを宣言することで、他の文字エンコーディングを使用可能(オプション)'))
|
238
|
+
|
239
|
+
= How REXML processes XML.(1)\n(('note:REXML の XML処理方法(1)'))
|
240
|
+
|
241
|
+
* REXML supports UTF-8 and UTF-16. \n
|
242
|
+
(('note:REXML は UTF-8 と UTF-16 をサポート'))
|
243
|
+
* Reads and parses XML files by tags.\n
|
244
|
+
(('note:XMLファイルをタグ単位で読み込み、パース処理を行う'))
|
245
|
+
|
246
|
+
= How REXML processes XML.(2)\n(('note:REXML の XML処理方法(2)'))
|
247
|
+
|
248
|
+
* For non-UTF-8 encoding, convert to UTF-8 when reading.\n
|
249
|
+
(('note:UTF-8 以外のエンコーディングの場合は、読み込み時にUTF-8 に変換'))
|
250
|
+
* Other encoding can basically be used if Ruby supports it.\n
|
251
|
+
(('note:Rubyがサポートしていれば他のエンコーディングも基本的に使用可能'))
|
252
|
+
|
253
|
+
= About REXML's Parser\n(('note:REXMLのパーサーについて'))
|
254
|
+
|
255
|
+
* REXML has a DOM/SAX2/Pull/Stream parser.\n
|
256
|
+
(('note:REXML はDOM/SAX2/Pull/Stream のパーサーがある'))
|
257
|
+
|
258
|
+
= Types of REXML parsers\n(('note:REXMLのパーサーの種類'))
|
259
|
+
|
260
|
+
* Tree API (('note:ツリーAPI'))
|
261
|
+
* DOM(Document Object Model) parser
|
262
|
+
* Streaming API (('note:ストリーミングAPI'))
|
263
|
+
* Callback type(passive) (('note:コールバック形式(受動的)'))
|
264
|
+
* SAX2 (Simple API for XML) parser
|
265
|
+
* Stream parser
|
266
|
+
* Pull type(active) (('note:Pull形式(能動的)'))
|
267
|
+
* Pull parser
|
268
|
+
|
269
|
+
= Features of DOM parser.\n(('note:DOMパーサーの特徴'))
|
270
|
+
|
271
|
+
* DOM-style XML parser.\n
|
272
|
+
(('note:DOM スタイルの XML パーサ'))
|
273
|
+
* Treat XML as a tree structure.\n
|
274
|
+
(('note:XMLを木構造として扱う'))
|
275
|
+
* Easy to use as any node can be accessed.\n
|
276
|
+
(('note:任意のノードにアクセス可能なので使いやすい'))
|
277
|
+
* Keep parsing results in memory.\n
|
278
|
+
(('note:パース処理結果をメモリ上に保持する'))
|
279
|
+
* Large XML is memory inefficient and slow..\n
|
280
|
+
(('note:大きなXMLではメモリ効率が悪く遅い'))
|
281
|
+
|
282
|
+
= Features of SAX2 parser.(1)\n(('note:SAX2パーサーの特徴(1)'))
|
283
|
+
|
284
|
+
* Stream-style parser with API equivalent to SAX2.\n
|
285
|
+
(('note:SAX2 と同等の API を持つストリーム形式のパーサ '))
|
286
|
+
* Sequential processing from the beginning of the file, line by line.\n
|
287
|
+
(('note:ファイル先頭からシーケンシャルに1行単位ごとに処理'))
|
288
|
+
* By registering an event listener, callbacks are processed on an event-by-event basis.\n
|
289
|
+
(('note:イベントリスナを登録することでイベント単位にコールバック処理'))
|
290
|
+
|
291
|
+
= Features of SAX2 parser.(2)\n(('note:SAX2パーサーの特徴(2)'))
|
292
|
+
* Not keep parsing results in memory.\n
|
293
|
+
(('note:パース処理結果をメモリ上に保持しない'))
|
294
|
+
* Memory efficient, fast even with large XML.\n
|
295
|
+
(('note:メモリ効率に優れ、大きなXMLでも高速'))
|
296
|
+
* Not easy to use, because access to arbitrary nodes is not possible.\n
|
297
|
+
(('note:任意のノードへのアクセスはできないので、使い勝手は悪い'))
|
298
|
+
|
299
|
+
= Features of Stream parser.\n(('note:Streamパーサーの特徴'))
|
300
|
+
* Basically the same as SAX2 parser.\n
|
301
|
+
(('note:基本的には SAX2 パーサーと同じ'))
|
302
|
+
* Stream parsers are lightweight and fast because of their limited functionality.\n
|
303
|
+
(('note:Streamパーサーは 機能が限定的なので軽量のため速い'))
|
304
|
+
|
305
|
+
= Features of Pull parser.\n(('note:Pullパーサーの特徴'))
|
306
|
+
* Stream-style parser, processing one line at a time.\n
|
307
|
+
(('note:ストリーム形式のパーサで、1行単位に処理する'))
|
308
|
+
* Pull parser reads and processes each event by itself.\n
|
309
|
+
(('note:Pullパーサーは各イベントを自分で読み込んで処理する'))
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
= Motivation(1)\n(('note:動機(1)'))
|
314
|
+
|
315
|
+
* I am the author of the PDF export library ((<RBPDF gem|URL:https://github.com/naitoh/rbpdf/>)).\n
|
316
|
+
(('note:私は PDF出力ライブラリRBPDF gemの作者'))
|
317
|
+
* RBPDF is used by ((*Redmine*))'s PDF output feature.\n
|
318
|
+
(('note:RBPDF は ((*Redmine*)) のPDF出力機能で使用されている'))
|
319
|
+
* I would like to support PDF output of SVG images in RBPDF using REXML, which is easy to install.\n
|
320
|
+
(('note:インストールの容易なREXMLを用いてRBPDFでSVG画像のPDF出力をサポートしたい'))
|
321
|
+
|
322
|
+
= Motivation(2)\n(('note:動機(2)'))
|
323
|
+
|
324
|
+
* REXML performance is slower than C extension gem.\n
|
325
|
+
(('note:REXMLはパフォーマンスがC拡張gemより遅い'))
|
326
|
+
* I would like to improve REXML performance.\n
|
327
|
+
(('note:REXMLのパフォーマンスを改善したい'))
|
328
|
+
|
329
|
+
|
330
|
+
= Improvements\n(('note:改善点'))
|
331
|
+
|
332
|
+
* Up to 50% speedup between rexml 3.2.6 (Ruby 3.3.0 attached) and rexml 3.4.0 (Ruby 3.4.0 attached).\n
|
333
|
+
(('note:rexml 3.2.6(Ruby 3.3.0 添付) から、rexml 3.4.0(Ruby 3.4.0 添付) の間で最大50%の高速化を実現'))
|
334
|
+
* It is up to ((*60%*)) faster between rexml 3.2.6 and rexml 3.4.1.\n
|
335
|
+
(('note:rexml 3.2.6 から rexml 3.4.1 の間で((*最大60%*))の高速化を実現'))
|
336
|
+
|
337
|
+
= How?\n(('note:どうやって?'))
|
338
|
+
|
339
|
+
# img
|
340
|
+
# src = images/rubykaigi-2019-p35-p78.png
|
341
|
+
# relative_height = 60
|
342
|
+
|
343
|
+
(('tag:center'))
|
344
|
+
(('tag:small'))
|
345
|
+
"Improving CSV Processing with Ruby 2.6"\n
|
346
|
+
at RubyKaigi 2019\n
|
347
|
+
(('note:((<URL:https://slide.rabbit-shocker.org/authors/kou/rubykaigi-2019/>))'))
|
348
|
+
|
349
|
+
= What is StringScanner?(1)\n(('note:StringScanner とは?(1)'))
|
350
|
+
|
351
|
+
* StringScanner is a sequential string scanner.\n
|
352
|
+
(('note:StringScanner は逐次的な文字列スキャナ'))
|
353
|
+
* Sequential String Scanning\n(('note:文字列の逐次スキャン'))
|
354
|
+
* Regular Expression Matching\n(('note:正規表現マッチング'))
|
355
|
+
* State Management\n(('note:状態管理'))
|
356
|
+
|
357
|
+
|
358
|
+
= StringScanner Features(1)\n(('note:StringScanner の特徴(1)'))
|
359
|
+
|
360
|
+
* Sequential String Scanning\n(('note:文字列の逐次スキャン'))
|
361
|
+
* It processes a string from the beginning, moving forward as it matches patterns.\n
|
362
|
+
(('note:文字列の先頭から順番に解析しながら先に進む'))
|
363
|
+
* Regular Expression Matching\n(('note:正規表現マッチング'))
|
364
|
+
* State Management\n(('note:状態管理'))
|
365
|
+
|
366
|
+
= StringScanner Features(2)\n(('note:StringScanner の特徴(2)'))
|
367
|
+
|
368
|
+
* Sequential String Scanning\n(('note:文字列の逐次スキャン'))
|
369
|
+
* Regular Expression Matching\n(('note:正規表現マッチング'))
|
370
|
+
* Use scan(), scan_until(), etc. to look for specific patterns.\n
|
371
|
+
(('note:scan(), scan_until() などを使って特定のパターンを探す。'))
|
372
|
+
* State Management\n(('note:状態管理'))
|
373
|
+
|
374
|
+
= StringScanner Features(3)\n(('note:StringScanner の特徴(3)'))
|
375
|
+
|
376
|
+
* Sequential String Scanning\n(('note:文字列の逐次スキャン'))
|
377
|
+
* Regular Expression Matching\n(('note:正規表現マッチング'))
|
378
|
+
* State Management\n(('note:状態管理'))
|
379
|
+
* pos (current position) and rest (rest of string) to see how far you have parsed.\n
|
380
|
+
(('note:pos (現在の位置) や rest (残りの文字列) で、どこまで解析したかを把握できる'))
|
381
|
+
|
382
|
+
= What is StringScanner?(2)\n(('note:StringScanner とは?(2)'))
|
383
|
+
* Available since Ruby 1.8 and default gem since Ruby 2.5.\n
|
384
|
+
(('note:Ruby 1.8 から使用可能で Ruby 2.5 以降で default gem になっている'))
|
385
|
+
* Uses Ruby's regular expression engine (Onigmo).\n
|
386
|
+
(('note:Rubyの正規表現エンジン(Onigmo)を使っている'))
|
387
|
+
* ReDoS countermeasure implemented in Ruby 3.2 is also effective.👍\n
|
388
|
+
(('note:Ruby 3.2で実装されたReDoS対策も有効'))
|
389
|
+
|
390
|
+
= StringScanner is fast.(1)\n(('note:StringScanner は速い(1)'))
|
391
|
+
|
392
|
+
# rouge ruby
|
393
|
+
|
394
|
+
/\A\w+/.match('test string') #=> 'test'
|
395
|
+
s = StringScanner.new('test string')
|
396
|
+
s.check(/\w+/) #=> 'test'
|
397
|
+
s.check('test') #=> 'test'
|
398
|
+
|
399
|
+
# RT
|
400
|
+
|
401
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center'))(('tag:small')) 5.675M i/s
|
402
|
+
(('tag:center'))(('tag:small'))StringScanner\n#check(Regexp), (('tag:center'))(('tag:small')) 8.800M i/s\n (('note:(1.55x faster)'))
|
403
|
+
(('tag:center'))(('tag:small'))StringScanner\n#check(String), (('tag:center'))(('tag:small')) 10.27M i/s\n (('note:(1.81x faster)'))
|
404
|
+
|
405
|
+
= StringScanner is fast.(2)\n(('note:StringScanner は速い(2)'))
|
406
|
+
|
407
|
+
# RT
|
408
|
+
|
409
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center'))(('tag:small')) 5.675M i/s
|
410
|
+
(('tag:center'))(('tag:small'))StringScanner\n#check(Regexp), (('tag:center'))(('tag:small')) 8.800M i/s\n (('note:(1.55x faster)'))
|
411
|
+
(('tag:center'))(('tag:small'))StringScanner\n#check(String), (('tag:center'))(('tag:small')) 10.27M i/s\n (('note:(((*1.81x*)) faster)'))
|
412
|
+
|
413
|
+
* StringScanner#check(String) is fast because it uses ((*memcmp()*)) for comparison.\n
|
414
|
+
(('note:StringScanner#check(String) は比較に ((*memcmp()*)) を使うので速い'))
|
415
|
+
|
416
|
+
= StringScanner is fast.(3)\n(('note:StringScanner は速い(3)'))
|
417
|
+
|
418
|
+
# RT
|
419
|
+
|
420
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center'))(('tag:small')) 5.675M i/s
|
421
|
+
(('tag:center'))(('tag:small'))StringScanner\n#check(Regexp), (('tag:center'))(('tag:small')) 8.800M i/s\n (('note:(1.55x faster)'))
|
422
|
+
|
423
|
+
* Regexp#match generates and returns a MatchData Object.\n
|
424
|
+
(('note:Regexp#match は MatchData Object を生成して返す'))
|
425
|
+
* StringScanner#check copies the matched string and returns it.\n
|
426
|
+
(('note:StringScanner#check はマッチした文字列をコピーして返す'))
|
427
|
+
|
428
|
+
= Without match object generation, performance is equivalent.\n(('note:マッチオブジェクト生成無しの場合、性能は同等'))
|
429
|
+
|
430
|
+
# RT
|
431
|
+
|
432
|
+
(('tag:center'))(('tag:small'))Regexp#match?, (('tag:center')) 14.71M i/s
|
433
|
+
(('tag:center'))(('tag:small'))StringScanner#match?, (('tag:center')) 14.28M i/s (('note:(1.03x slower)'))
|
434
|
+
|
435
|
+
* Regexp#match? and StringScanner\n#match? respond with boolean.\n
|
436
|
+
(('note:Regexp#match?とStringScanner#match? はboolean で応答'))
|
437
|
+
* Performance is equivalent since both are only regular expression processing.\n
|
438
|
+
(('note:両方とも正規表現処理のみなのでパフォーマンスは同等'))
|
439
|
+
|
440
|
+
= rexml in Ruby 3.4 (2)\n(('note:Ruby 3.4のrexml(2)'))
|
441
|
+
|
442
|
+
(('tag:small:Use StringScanner#scan'))\n
|
443
|
+
(('tag:small:instead of Regexp#match'))\n
|
444
|
+
(('tag:small:to parse XML.'))\n
|
445
|
+
(('note:XMLのパースにRegexp#matchの代わりにStringScanner#scanを使う'))
|
446
|
+
|
447
|
+
= Example of Regexp class use\n(('note:Regexpクラスを使う例'))
|
448
|
+
|
449
|
+
* Repeat until a match is found in the regular expression.\n
|
450
|
+
(('note:正規表現でマッチするまで繰り返す'))
|
451
|
+
|
452
|
+
# rouge ruby
|
453
|
+
|
454
|
+
word = (/\A<[^>]*>/um).match('<!-- foo -->') # Get Tag
|
455
|
+
case word[0]
|
456
|
+
when /\A<\?xml\s/u 👈 Not Match
|
457
|
+
when /\A<!--/u
|
458
|
+
/<!--(.*?)-->/um.match(word[0])[0] #=> " foo "
|
459
|
+
when /\A<!DOCTYPE\s/um
|
460
|
+
|
461
|
+
= Example of Regexp class use\n(('note:Regexpクラスを使う例'))
|
462
|
+
|
463
|
+
* Repeat until a match is found in the regular expression.\n
|
464
|
+
(('note:正規表現でマッチするまで繰り返す'))
|
465
|
+
|
466
|
+
# rouge ruby
|
467
|
+
|
468
|
+
word = (/\A<[^>]*>/um).match('<!-- foo -->') # Get Tag
|
469
|
+
case word[0]
|
470
|
+
when /\A<\?xml\s/u
|
471
|
+
when /\A<!--/u 👈 Match
|
472
|
+
/<!--(.*?)-->/um.match(word[0])[0] #=> " foo "
|
473
|
+
when /\A<!DOCTYPE\s/um
|
474
|
+
|
475
|
+
|
476
|
+
= Example of StringScanner use(1)\n(('note:StringScannerの使用例(1)'))
|
477
|
+
|
478
|
+
* Parses strings sequentially from the beginning.\n
|
479
|
+
(('note:文字列の先頭から順番に解析する'))
|
480
|
+
* Easy to understand process.\n
|
481
|
+
(('note:処理がわかりやすい'))
|
482
|
+
|
483
|
+
= Example of StringScanner use(1)\n(('note:StringScannerの使用例(1)'))
|
484
|
+
|
485
|
+
# rouge ruby
|
486
|
+
|
487
|
+
s = StringScanner.new('<!-- foo -->')
|
488
|
+
s.pos = 0 # for Benchmark
|
489
|
+
if s.scan("<?") 👈 Not Match
|
490
|
+
elsif s.scan("<!")
|
491
|
+
if s.scan("--")
|
492
|
+
s.scan(/(.*?)-->/um) and s[1] #=> " foo "
|
493
|
+
elsif s.scan("DOCTYPE")
|
494
|
+
|
495
|
+
# RT
|
496
|
+
|
497
|
+
(('tag:center'))<,(('tag:center'))!,(('tag:center'))-,(('tag:center'))-, ,(('tag:center'))f,(('tag:center'))o,(('tag:center'))o, ,(('tag:center'))-,(('tag:center'))-,(('tag:center'))>
|
498
|
+
|
499
|
+
☝️, , , , , , , , , , ,
|
500
|
+
|
501
|
+
= Example of StringScanner use(1)\n(('note:StringScannerの使用例(1)'))
|
502
|
+
|
503
|
+
# rouge ruby
|
504
|
+
|
505
|
+
s = StringScanner.new('<!-- foo -->')
|
506
|
+
s.pos = 0 # for Benchmark
|
507
|
+
if s.scan("<?")
|
508
|
+
elsif s.scan("<!") 👈 Match
|
509
|
+
if s.scan("--")
|
510
|
+
s.scan(/(.*?)-->/um) and s[1] #=> " foo "
|
511
|
+
elsif s.scan("DOCTYPE")
|
512
|
+
|
513
|
+
# RT
|
514
|
+
|
515
|
+
(('tag:center'))<,(('tag:center'))!,(('tag:center'))-,(('tag:center'))-, ,(('tag:center'))f,(('tag:center'))o,(('tag:center'))o, ,(('tag:center'))-,(('tag:center'))-,(('tag:center'))>
|
516
|
+
|
517
|
+
▶︎,▶︎,☝️, , , , , , , , ,
|
518
|
+
|
519
|
+
= Example of StringScanner use(1)\n(('note:StringScannerの使用例(1)'))
|
520
|
+
|
521
|
+
# rouge ruby
|
522
|
+
|
523
|
+
s = StringScanner.new('<!-- foo -->')
|
524
|
+
s.pos = 0 # for Benchmark
|
525
|
+
if s.scan("<?")
|
526
|
+
elsif s.scan("<!") 👈
|
527
|
+
if s.scan("--") 👈 Match
|
528
|
+
s.scan(/(.*?)-->/um) and s[1] #=> " foo "
|
529
|
+
elsif s.scan("DOCTYPE")
|
530
|
+
|
531
|
+
# RT
|
532
|
+
|
533
|
+
(('tag:center'))<,(('tag:center'))!,(('tag:center'))-,(('tag:center'))-, ,(('tag:center'))f,(('tag:center'))o,(('tag:center'))o, ,(('tag:center'))-,(('tag:center'))-,(('tag:center'))>
|
534
|
+
|
535
|
+
, ,▶︎,▶︎,☝️, , , , , , ,
|
536
|
+
|
537
|
+
= Example of StringScanner use(1)\n(('note:StringScannerの使用例(1)'))
|
538
|
+
|
539
|
+
# rouge ruby
|
540
|
+
|
541
|
+
s = StringScanner.new('<!-- foo -->')
|
542
|
+
s.pos = 0 # for Benchmark
|
543
|
+
if s.scan("<?")
|
544
|
+
elsif s.scan("<!") 👈
|
545
|
+
if s.scan("--") 👈
|
546
|
+
s.scan(/(.*?)-->/um) and s[1] #=> " foo "👈
|
547
|
+
elsif s.scan("DOCTYPE")
|
548
|
+
|
549
|
+
# RT
|
550
|
+
|
551
|
+
(('tag:center'))<,(('tag:center'))!,(('tag:center'))-,(('tag:center'))-, ,(('tag:center'))f,(('tag:center'))o,(('tag:center'))o, ,(('tag:center'))-,(('tag:center'))-,(('tag:center'))>
|
552
|
+
|
553
|
+
, , , ,▶︎,▶︎,▶︎,▶︎,▶︎,▶︎,▶︎,☝️
|
554
|
+
|
555
|
+
= Benchmark result\n(('note:ベンチマーク結果'))
|
556
|
+
|
557
|
+
# RT
|
558
|
+
|
559
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center')) 1.210M i/s
|
560
|
+
(('tag:center'))(('tag:small'))StringScanner#scan, (('tag:center')) 2.225M i/s\n (('note:(1.84x faster)'))
|
561
|
+
|
562
|
+
* Using StringScanner is 1.8 times faster.\n
|
563
|
+
(('note:StringScanner を使った方が 1.8 倍速い'))
|
564
|
+
|
565
|
+
= rexml in Ruby 3.4 (3)\n(('note:Ruby 3.4のrexml(3)'))
|
566
|
+
|
567
|
+
(('tag:center'))
|
568
|
+
(('tag:small:Use StringScanner#scan_until'))\n
|
569
|
+
(('tag:small:instead of Regexp#match'))\n
|
570
|
+
(('tag:small:to parse XML.'))\n
|
571
|
+
(('note:XMLのパースにRegexp#matchの代わりにStringScanner#scan_until を使う'))
|
572
|
+
|
573
|
+
# rouge ruby
|
574
|
+
|
575
|
+
s = StringScanner.new('test string')
|
576
|
+
s.scan_until(/str/) # => "test str"
|
577
|
+
|
578
|
+
= Regexp Class
|
579
|
+
|
580
|
+
# rouge ruby
|
581
|
+
|
582
|
+
xml = "<![CDATA[#{'a'*n}]]>"
|
583
|
+
md = xml.match(/\A<!\[CDATA\[(.*?)\]\]>/um)
|
584
|
+
md[1]
|
585
|
+
=> "aaa.."
|
586
|
+
|
587
|
+
# RT
|
588
|
+
|
589
|
+
, (('tag:center'))(('tag:small'))n=10,(('tag:center'))(('tag:small'))n=100
|
590
|
+
|
591
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center'))(('tag:small'))2856k i/s, (('tag:center'))(('tag:small'))976k i/s
|
592
|
+
|
593
|
+
= StringScanner#check(Regexp)
|
594
|
+
|
595
|
+
# rouge ruby
|
596
|
+
|
597
|
+
s = StringScanner.new("<![CDATA[#{'a'*n}]]>")
|
598
|
+
s.check(/<!\[CDATA\[(.*?)\]\]>/um) and s[1]
|
599
|
+
=> "aaa.."
|
600
|
+
|
601
|
+
# RT
|
602
|
+
|
603
|
+
, (('tag:center'))(('tag:small'))n=10,(('tag:center'))(('tag:small'))n=100
|
604
|
+
|
605
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center'))(('tag:small'))2856k i/s, (('tag:center'))(('tag:small'))976k i/s
|
606
|
+
(('tag:center'))(('tag:small'))#scan\n(Regexp), (('tag:center'))(('tag:small'))4146k i/s\n (('note:(1.45x faster)')), (('tag:center'))(('tag:small'))1137k i/s\n (('note:(1.16x faster)'))
|
607
|
+
|
608
|
+
* (('tag:small'))Using StringScanner is 1.45 times faster.\n
|
609
|
+
(('note:StringScanner を使った方が 1.45 倍速い'))
|
610
|
+
|
611
|
+
= StringScanner#scan_until String
|
612
|
+
|
613
|
+
# rouge ruby
|
614
|
+
|
615
|
+
s = StringScanner.new("<![CDATA[#{'a'*n}]]>")
|
616
|
+
s.pos = 0 and s.skip("<!") and s.skip("[CDATA[")\
|
617
|
+
and s.scan_until("]]>").chomp!("]]>") #=>"aaa.."
|
618
|
+
|
619
|
+
# RT
|
620
|
+
|
621
|
+
, (('tag:center'))(('tag:small'))n=10,(('tag:center'))(('tag:small'))n=100
|
622
|
+
|
623
|
+
(('tag:center'))(('tag:small'))Regexp#match, (('tag:center'))(('tag:small'))2856k i/s, (('tag:center'))(('tag:small'))976k i/s
|
624
|
+
(('tag:center'))(('tag:small'))#scan\n(Regexp), (('tag:center'))(('tag:small'))4146k i/s\n (('note:(1.45x faster)')), (('tag:center'))(('tag:small'))1137k i/s\n (('note:(1.16x faster)'))
|
625
|
+
(('tag:center'))(('tag:small'))#scan_until\n(String), (('tag:center'))(('tag:small'))4513k i/s\n (('note:(1.58x faster)')), (('tag:center'))(('tag:small'))3574k i/s\n (('note:(((*3.66x*)) faster)'))
|
626
|
+
|
627
|
+
* (('tag:small'))Using scan_until(String) is 3.6 times faster and less degrading.
|
628
|
+
(('note:scan_until(String) の方が3.6倍速く、劣化しにくい'))
|
629
|
+
|
630
|
+
= rexml in Ruby 3.4 (3)\n(('note:Ruby 3.4のrexml(3)'))
|
631
|
+
|
632
|
+
* Using string matching\n (instead of regular expressions)\n is faster.\n
|
633
|
+
(('note:(正規表現の代わりに)文字列マッチを使うと、より高速'))
|
634
|
+
* Even when match strings are long, performance degradation is minimized.\n
|
635
|
+
(('note:マッチ文字列が長くなっても、性能劣化を最小限に抑えられる'))
|
636
|
+
|
637
|
+
= StringScanner#scan_until String
|
638
|
+
|
639
|
+
* ((<strscan#106|URL:https://github.com/ruby/strscan/pull/106>)) Support for string matching in strscan 3.1.2(attached to Ruby 3.4.0).\n(('note:(Ruby 3.4.0添付の)strscan 3.1.2 で文字列マッチに対応'))
|
640
|
+
* StringScanner#scan_until(String) is fast because it uses ((*rb_memsearch()*)) for comparison.\n
|
641
|
+
(('note:StringScanner#scan_until(String) は比較に ((*rb_memsearch()*)) を使うので速い'))
|
642
|
+
|
643
|
+
= rexml in Ruby 3.4 (4)\n(('note:Ruby 3.4のrexml(4)'))
|
644
|
+
|
645
|
+
(('tag:small:Suppress generation of'))\n
|
646
|
+
(('tag:small:unnecessary String Objects.'))\n
|
647
|
+
(('note:不要な String Object の生成を抑制する'))
|
648
|
+
|
649
|
+
= Generating String Object (copying data) takes time\n(('note:文字列 Object の生成(データのコピー)に時間がかかる'))
|
650
|
+
|
651
|
+
# rouge ruby
|
652
|
+
|
653
|
+
s = StringScanner.new(' ')
|
654
|
+
s.check(/\s+/um) #=> " "
|
655
|
+
s.match?(/\s+/um) #=> 1
|
656
|
+
|
657
|
+
* No match string needed for whitespace removal.\n
|
658
|
+
(('note:空白除去の場合はマッチ文字列は不要'))
|
659
|
+
|
660
|
+
= Benchmark result
|
661
|
+
|
662
|
+
* Faster if no match string is needed.\n
|
663
|
+
(('note:マッチ文字列不要なら速くなる'))
|
664
|
+
|
665
|
+
# RT
|
666
|
+
|
667
|
+
, /\s+/um
|
668
|
+
|
669
|
+
(('tag:center'))check, (('tag:left'))6686K i/s
|
670
|
+
(('tag:center'))match?, (('tag:left'))8925K i/s (('note:(1.33x faster)'))
|
671
|
+
|
672
|
+
= String matching is faster.(1)\n(('note:文字列マッチならより高速(1)'))
|
673
|
+
|
674
|
+
# rouge ruby
|
675
|
+
|
676
|
+
s = StringScanner.new('<![CDATA[')
|
677
|
+
if s.check(/<!/um) .. #=> "<!"
|
678
|
+
if s.match?(/<!/um) .. #=> 2
|
679
|
+
if s.check('<!') .. #=> "<!"
|
680
|
+
if s.match?('<!') .. #=> 2
|
681
|
+
|
682
|
+
* Branching process does not need match string.
|
683
|
+
(('note: 分岐処理ではマッチ文字列は不要'))
|
684
|
+
|
685
|
+
|
686
|
+
= String matching is faster.(2)\n(('note:文字列マッチならより高速(2)'))
|
687
|
+
|
688
|
+
* Faster if no match string is needed.\n
|
689
|
+
(('note:マッチ文字列不要なら速くなる'))
|
690
|
+
* String matching is faster.\n
|
691
|
+
(('note:文字列マッチならより高速'))
|
692
|
+
|
693
|
+
# RT
|
694
|
+
|
695
|
+
, /<!/um, '<!'
|
696
|
+
|
697
|
+
(('tag:center'))check, (('tag:center'))10525K i/s, (('tag:center'))14450K i/s (('note:(1.37x faster)'))
|
698
|
+
(('tag:center'))match?, (('tag:center'))18731K i/s (('note:(1.78x faster)')), (('tag:center'))31900K i/s (('note:(3.03x faster)'))
|
699
|
+
|
700
|
+
|
701
|
+
= Avoid generating String object(1)\n(('note:文字列オブジェクトの生成を避ける(1)'))
|
702
|
+
|
703
|
+
# rouge ruby
|
704
|
+
|
705
|
+
s = StringScanner.new("'test'>")
|
706
|
+
s.check(/(['"])/) #=> "'"
|
707
|
+
|
708
|
+
* Need to determine if double or single quotes are used to get attribute values.\n
|
709
|
+
(('note:属性値を取得するためにダブルクォーテーションかシングルクォーテーションかの判断が必要'))
|
710
|
+
|
711
|
+
= Avoid generating String object(2)\n(('note:文字列オブジェクトの生成を避ける(2)'))
|
712
|
+
|
713
|
+
# rouge ruby
|
714
|
+
|
715
|
+
s = StringScanner.new("'test'>")
|
716
|
+
case s.peek_byte
|
717
|
+
when 34 then '"' # '"'.ord
|
718
|
+
when 39 then "'" # "'".ord
|
719
|
+
end #=> "'"
|
720
|
+
|
721
|
+
* If a single byte is returned as a number, no object is created.\n
|
722
|
+
(('note: 1バイトなら数値で返せば、オブジェクトは生成されない'))
|
723
|
+
|
724
|
+
= Benchmark result
|
725
|
+
|
726
|
+
* Faster without object generation.\n
|
727
|
+
(('note:オブジェクト生成無しでより速く'))
|
728
|
+
|
729
|
+
# RT
|
730
|
+
|
731
|
+
(('tag:center'))with object, (('tag:left'))10385k i/s
|
732
|
+
(('tag:center'))without object, (('tag:left'))32000K i/s (('note:(3.08x faster)'))
|
733
|
+
|
734
|
+
= StringScanner#peek_byte
|
735
|
+
|
736
|
+
* New methods added in strscan 3.1.2 (attached to Ruby 3.4.0)\n(('note:(Ruby 3.4.0添付の)strscan 3.1.2 で追加された新しいメソッド'))
|
737
|
+
* Referring to ((<Fast Route Parsing in Rails (('tag:small:(by Aaron Patterson)'))|URL:https://www.youtube.com/watch?v=ZE6F3drGhA8>>)), REXML was also made faster using peek_byte.\n
|
738
|
+
(('note:Fast Route Parsing in Rails の話を参考に、REXML も peek_byte を使って速くなりました'))
|
739
|
+
|
740
|
+
= rexml in Ruby 3.4 (5)\n(('note:Ruby 3.4のrexml(5)'))
|
741
|
+
|
742
|
+
(('tag:small:Use constants or memoization'))\n
|
743
|
+
(('tag:small:for slow processes.'))\n
|
744
|
+
(('note:遅い処理には定数やメモ化を使う'))
|
745
|
+
|
746
|
+
= Regexp.escape is slow, so use Constant.\n(('note:Regexp.escape は遅いので定数化'))
|
747
|
+
|
748
|
+
# rouge ruby
|
749
|
+
|
750
|
+
REG = /#{Regexp.escape("'")}/
|
751
|
+
s = StringScanner.new("test'>")
|
752
|
+
s.check_until(REG)
|
753
|
+
|
754
|
+
# RT
|
755
|
+
|
756
|
+
(('tag:center'))not use Constant, (('tag:left'))1393K i/s
|
757
|
+
(('tag:center'))use Constant, (('tag:left'))9660K i/s (('note:(6.93x faster)'))
|
758
|
+
|
759
|
+
= Encoding of the read delimiter.\n(('note: 読み取り区切り文字のエンコード'))
|
760
|
+
|
761
|
+
* REXML reads XML with ">" as read delimiter.\n
|
762
|
+
(('note:REXML は ">" を読み込み区切り文字としてXMLを読み込む'))
|
763
|
+
* In UTF-16, ">" is 2 byte.\n
|
764
|
+
(('note: UTF-16 の場合、">" は 2byte'))
|
765
|
+
|
766
|
+
# RT
|
767
|
+
|
768
|
+
,(('tag:center'))<,,(('tag:center'))f,,(('tag:center'))o,,(('tag:center'))o,,(('tag:center'))>
|
769
|
+
|
770
|
+
, , , , , , , ,☝️,☝️
|
771
|
+
|
772
|
+
= Memorize the encoding result of the read delimiter.\n(('note:読み取り区切り文字のエンコード結果のメモ化'))
|
773
|
+
|
774
|
+
* One character code exists for each XML instance.\n
|
775
|
+
(('note:XMLインスタンス毎に文字コードは一つ存在'))
|
776
|
+
|
777
|
+
# rouge ruby
|
778
|
+
|
779
|
+
term = '>'
|
780
|
+
@term_encord ||= term.encode('UTF-16BE')
|
781
|
+
|
782
|
+
= ((*Made*)) REXML Fast Again!\n(('note:REXML を再び高速化した!'))
|
783
|
+
|
784
|
+
# img
|
785
|
+
# src = images/svg_327.svg
|
786
|
+
# relative_height = 100
|
787
|
+
|
788
|
+
== Slide properties
|
789
|
+
|
790
|
+
: enable-title-on-image
|
791
|
+
false
|
792
|
+
|
793
|
+
= Other improvements.\n(('note:他の改善点'))
|
794
|
+
|
795
|
+
* Enhanced invalid XML check.\n
|
796
|
+
(('note:無効XMLチェック強化'))
|
797
|
+
* Unification of processing results for each REXML parser (DOM/SAX2/Pull/Stream).\n
|
798
|
+
(('note:各パーサー間でのパース処理結果の統一'))
|
799
|
+
|
800
|
+
= Enhanced invalid XML check(1).\n(('note:無効XMLチェック強化(1)'))
|
801
|
+
|
802
|
+
# rouge xml
|
803
|
+
|
804
|
+
<root1></root1>
|
805
|
+
<root2></root2>
|
806
|
+
|
807
|
+
* Multiple root tags.\n
|
808
|
+
(('note:複数のルートタグ'))
|
809
|
+
|
810
|
+
= Enhanced invalid XML check(2).\n(('note:無効XMLチェック強化(2)'))
|
811
|
+
|
812
|
+
# rouge xml
|
813
|
+
|
814
|
+
foo
|
815
|
+
<root></root>
|
816
|
+
|
817
|
+
* String before the root tag.\n
|
818
|
+
(('note:ルートタグ前の文字列'))
|
819
|
+
* ((<rexml#212|URL:https://github.com/ruby/rexml/issues/212>)): If the BOM is broken, it is interpreted as a string and can detect errors.\n
|
820
|
+
(('note:BOMが壊れた場合、文字列と解釈されるのでエラー検出できる。'))
|
821
|
+
|
822
|
+
= Enhanced invalid XML check(3).\n(('note:無効XMLチェック強化(3)'))
|
823
|
+
|
824
|
+
# rouge xml
|
825
|
+
|
826
|
+
<root></root>
|
827
|
+
bar
|
828
|
+
|
829
|
+
* String after the root tag.\n
|
830
|
+
(('note:ルートタグ後の文字列'))
|
831
|
+
|
832
|
+
= Enhanced invalid XML check(4).\n(('note:無効XMLチェック強化(4)'))
|
833
|
+
|
834
|
+
# rouge xml
|
835
|
+
|
836
|
+
429 Too Many Requests
|
837
|
+
|
838
|
+
* String with no root tag.\n
|
839
|
+
(('note:ルートタグが無い文字列'))
|
840
|
+
* If an error string is responded instead of XML, the XML parser can handle the error.\n
|
841
|
+
(('note:XMLではなくエラー文字列が応答された場合に、XMLパーサー側でエラー処理できる。'))
|
842
|
+
|
843
|
+
= Unification of processing results for each REXML parser.(1)\n(('note:各パーサー間でのパース処理結果の統一(1)'))
|
844
|
+
|
845
|
+
* REXML has a DOM/SAX2/Pull/Stream parser and there are differences in processing procedures'.\n
|
846
|
+
(('note:REXMLはDOM/SAX2/Pull/Streamパーサーがあり処理手順に差がある'))
|
847
|
+
* There was a difference in the parsing result, so it was fixed.\n
|
848
|
+
(('note:パース処理結果にも差異があったので修正した'))
|
849
|
+
|
850
|
+
= Unification of processing results for each REXML parser.(2)\n(('note:各パーサー間でのパース処理結果の統一(2)'))
|
851
|
+
|
852
|
+
* There were also differences in error handling items.\n
|
853
|
+
(('note:エラー処理項目にも差があった'))
|
854
|
+
* Some of the security measures were implemented only in the DOM parser.\n
|
855
|
+
(('note:セキュリティ対策の一部がDOMパーサーのみの実装だった'))
|
856
|
+
* ((<CVE-2024-41946: DoS vulnerability in REXML|URL:https://www.ruby-lang.org/en/news/2024/08/01/dos-rexml-cve-2024-41946/>))
|
857
|
+
* Fixed in REXML 3.3.3.\n
|
858
|
+
(('note:REXML 3.3.3 で修正済'))
|
859
|
+
|
860
|
+
= Summary: Performance(1)\n(('note:まとめ:性能(1)'))
|
861
|
+
|
862
|
+
* Use StringScanner instead of Regexp class to parse XML.\n
|
863
|
+
(('note:XMLのパースにRegexpクラスの代わりにStringScannerを使う'))
|
864
|
+
* Using string matching is faster.\n
|
865
|
+
(('note:文字列マッチを使うと、より高速'))
|
866
|
+
* Even when match strings are long, performance degradation is minimized.\n
|
867
|
+
(('note:マッチ文字列が長くなっても、性能劣化を最小限に抑えられる'))
|
868
|
+
|
869
|
+
= Summary: Performance(2)\n(('note:まとめ:性能(2)'))
|
870
|
+
|
871
|
+
* Avoiding generation of String object is faster.\n
|
872
|
+
(('note:文字列 Object の生成を避けると速い'))
|
873
|
+
* Use constants or memoization \nfor slow processes.\n
|
874
|
+
(('note:遅い処理には定数やメモ化を使う'))
|
875
|
+
* After eliminating bottlenecks, \nYJIT makes it even faster.\n
|
876
|
+
(('note:ボトルネックを解消後、YJITでさらに高速に'))
|
877
|
+
|
878
|
+
= Summary: Other improvements\n(('note:まとめ:他の改善点'))
|
879
|
+
|
880
|
+
* Enhanced invalid XML check.\n
|
881
|
+
(('note:無効XMLチェック強化'))
|
882
|
+
* Unification of processing results for each REXML parser (DOM/SAX2/Pull/Stream).\n
|
883
|
+
(('note:各パーサー間でのパース処理結果の統一'))
|
884
|
+
|
885
|
+
|
886
|
+
= Further work(1)\n(('note:今後の改善案(1)'))
|
887
|
+
|
888
|
+
* Further optimization with new StringScanner features.\n(('note:StringScannerの新機能を用いたさらなる最適化'))
|
889
|
+
* Use StringScanner#scan_until(String) and StringScanner#peek_byte more.\n
|
890
|
+
(('note:StringScanner#scan_until(String) や StringScanner#peek_byte をより使っていく'))
|
891
|
+
|
892
|
+
= Further work(2)\n(('note:今後の改善案(2)'))
|
893
|
+
|
894
|
+
# img
|
895
|
+
# src = images/rubykaigi-2019-p35-p78.png
|
896
|
+
# relative_height = 50
|
897
|
+
|
898
|
+
* (('tag:small'))Use StringScanner's new features in other gems.\n(('note:他のgem でもStringScannerの新機能を使う'))\n
|
899
|
+
* (('tag:small'))Enhanced StringScanner may also make CSV faster.\n(('note:StringScannerの強化により、CSVもより速くできるかもしれない'))
|
900
|
+
|
901
|
+
|
902
|
+
== Slide properties
|
903
|
+
|
904
|
+
: enable-title-on-image
|
905
|
+
false
|
data/theme.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
@title_slide_background_image = 'images/assets/rubykaigi2025_slide_title.png'
|
2
|
+
# colors
|
3
|
+
foreground = "#ffffff"
|
4
|
+
black = "#000000"
|
5
|
+
match TitleSlide do |slides|
|
6
|
+
slides.prop_set("foreground", foreground)
|
7
|
+
end
|
8
|
+
include_theme("title-slide-background-image")
|
9
|
+
|
10
|
+
@slide_logo_image_uninstall = true
|
11
|
+
include_theme("clear-code")
|
12
|
+
|
13
|
+
match(Slide, Table) do |e|
|
14
|
+
e.prop_set "size", screen_size(2 * Pango::SCALE)
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-naitoh-rubykaigi-2025
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- NAITOH Jun
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-04-16 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rabbit
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 2.0.2
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 2.0.2
|
26
|
+
description: https://rubykaigi.org/2025/
|
27
|
+
email:
|
28
|
+
- naitoh@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- ".rabbit"
|
34
|
+
- Improvement of REXML and speed up using StringScanner.pdf
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- config.yaml
|
38
|
+
- images/CVE-2024-35176.png
|
39
|
+
- images/RubyKaigi2024LT.png
|
40
|
+
- images/assets/rubykaigi2025_slide_title.png
|
41
|
+
- images/medpeer.png
|
42
|
+
- images/medpeer_mission.png
|
43
|
+
- images/rexml_x_1797256482272235856.png
|
44
|
+
- images/rubykaigi-2019-p35-p78.png
|
45
|
+
- images/svg_327.svg
|
46
|
+
- images/svg_340_jit_disable.svg
|
47
|
+
- images/svg_340_jit_enable.svg
|
48
|
+
- images/svg_341.svg
|
49
|
+
- images/svg_341_jit_disable.svg
|
50
|
+
- images/svg_341_jit_enable.svg
|
51
|
+
- pdf/rubykaigi-2025-rubykaigi-2025.pdf
|
52
|
+
- rubykaigi-2025.rab
|
53
|
+
- theme.rb
|
54
|
+
homepage: https://slide.rabbit-shocker.org/authors/naitoh/rubykaigi-2025/
|
55
|
+
licenses: []
|
56
|
+
metadata: {}
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
requirements: []
|
71
|
+
rubygems_version: 3.6.2
|
72
|
+
specification_version: 4
|
73
|
+
summary: Improvement of REXML and speed up using StringScanner
|
74
|
+
test_files: []
|