# HG changeset patch # User Daichi TOMA # Date 1392228168 -32400 # Node ID 7c7afe38c9d699729a55c95e04b73cdde1aca1a3 # Parent d15c924e9089b753613dc9c70455bf0778cda209 rewrite slides diff -r d15c924e9089 -r 7c7afe38c9d6 paper/benchmark/warp/warp2.eps --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/benchmark/warp/warp2.eps Thu Feb 13 03:02:48 2014 +0900 @@ -0,0 +1,667 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: warp2.eps +%%Creator: gnuplot 4.6 patchlevel 3 +%%CreationDate: Thu Feb 13 02:38:55 2014 +%%DocumentFonts: (atend) +%%BoundingBox: 50 50 410 302 +%%EndComments +%%BeginProlog +/gnudict 256 dict def +gnudict begin +% +% The following true/false flags may be edited by hand if desired. +% The unit line width and grayscale image gamma correction may also be changed. +% +/Color false def +/Blacktext false def +/Solid false def +/Dashlength 1 def +/Landscape false def +/Level1 false def +/Rounded false def +/ClipToBoundingBox false def +/SuppressPDFMark false def +/TransparentPatterns false def +/gnulinewidth 5.000 def +/userlinewidth gnulinewidth def +/Gamma 1.0 def +/BackgroundColor {-1.000 -1.000 -1.000} def +% +/vshift -46 def +/dl1 { + 10.0 Dashlength mul mul + Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if +} def +/dl2 { + 10.0 Dashlength mul mul + Rounded { currentlinewidth 0.75 mul add } if +} def +/hpt_ 31.5 def +/vpt_ 31.5 def +/hpt hpt_ def +/vpt vpt_ def +/doclip { + ClipToBoundingBox { + newpath 50 50 moveto 410 50 lineto 410 302 lineto 50 302 lineto closepath + clip + } if +} def +% +% Gnuplot Prolog Version 4.6 (September 2012) +% +%/SuppressPDFMark true def +% +/M {moveto} bind def +/L {lineto} bind def +/R {rmoveto} bind def +/V {rlineto} bind def +/N {newpath moveto} bind def +/Z {closepath} bind def +/C {setrgbcolor} bind def +/f {rlineto fill} bind def +/g {setgray} bind def +/Gshow {show} def % May be redefined later in the file to support UTF-8 +/vpt2 vpt 2 mul def +/hpt2 hpt 2 mul def +/Lshow {currentpoint stroke M 0 vshift R + Blacktext {gsave 0 setgray show grestore} {show} ifelse} def +/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R + Blacktext {gsave 0 setgray show grestore} {show} ifelse} def +/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R + Blacktext {gsave 0 setgray show grestore} {show} ifelse} def +/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def + /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def +/DL {Color {setrgbcolor Solid {pop []} if 0 setdash} + {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def +/BL {stroke userlinewidth 2 mul setlinewidth + Rounded {1 setlinejoin 1 setlinecap} if} def +/AL {stroke userlinewidth 2 div setlinewidth + Rounded {1 setlinejoin 1 setlinecap} if} def +/UL {dup gnulinewidth mul /userlinewidth exch def + dup 1 lt {pop 1} if 10 mul /udl exch def} def +/PL {stroke userlinewidth setlinewidth + Rounded {1 setlinejoin 1 setlinecap} if} def +3.8 setmiterlimit +% Default Line colors +/LCw {1 1 1} def +/LCb {0 0 0} def +/LCa {0 0 0} def +/LC0 {1 0 0} def +/LC1 {0 1 0} def +/LC2 {0 0 1} def +/LC3 {1 0 1} def +/LC4 {0 1 1} def +/LC5 {1 1 0} def +/LC6 {0 0 0} def +/LC7 {1 0.3 0} def +/LC8 {0.5 0.5 0.5} def +% Default Line Types +/LTw {PL [] 1 setgray} def +/LTb {BL [] LCb DL} def +/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def +/LT0 {PL [] LC0 DL} def +/LT1 {PL [4 dl1 2 dl2] LC1 DL} def +/LT2 {PL [2 dl1 3 dl2] LC2 DL} def +/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def +/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def +/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def +/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def +/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def +/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def +/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def +/Dia {stroke [] 0 setdash 2 copy vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V closepath stroke + Pnt} def +/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V + currentpoint stroke M + hpt neg vpt neg R hpt2 0 V stroke + } def +/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V closepath stroke + Pnt} def +/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M + hpt2 vpt2 neg V currentpoint stroke M + hpt2 neg 0 R hpt2 vpt2 V stroke} def +/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V closepath stroke + Pnt} def +/Star {2 copy Pls Crs} def +/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V closepath fill} def +/TriUF {stroke [] 0 setdash vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V closepath fill} def +/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V closepath stroke + Pnt} def +/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V closepath fill} def +/DiaF {stroke [] 0 setdash vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V closepath fill} def +/Pent {stroke [] 0 setdash 2 copy gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + closepath stroke grestore Pnt} def +/PentF {stroke [] 0 setdash gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + closepath fill grestore} def +/Circle {stroke [] 0 setdash 2 copy + hpt 0 360 arc stroke Pnt} def +/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def +/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def +/C1 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 90 arc closepath fill + vpt 0 360 arc closepath} bind def +/C2 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 90 180 arc closepath fill + vpt 0 360 arc closepath} bind def +/C3 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 180 arc closepath fill + vpt 0 360 arc closepath} bind def +/C4 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 180 270 arc closepath fill + vpt 0 360 arc closepath} bind def +/C5 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 90 arc + 2 copy moveto + 2 copy vpt 180 270 arc closepath fill + vpt 0 360 arc} bind def +/C6 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 90 270 arc closepath fill + vpt 0 360 arc closepath} bind def +/C7 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 270 arc closepath fill + vpt 0 360 arc closepath} bind def +/C8 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 270 360 arc closepath fill + vpt 0 360 arc closepath} bind def +/C9 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 270 450 arc closepath fill + vpt 0 360 arc closepath} bind def +/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill + 2 copy moveto + 2 copy vpt 90 180 arc closepath fill + vpt 0 360 arc closepath} bind def +/C11 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 180 arc closepath fill + 2 copy moveto + 2 copy vpt 270 360 arc closepath fill + vpt 0 360 arc closepath} bind def +/C12 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 180 360 arc closepath fill + vpt 0 360 arc closepath} bind def +/C13 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 0 90 arc closepath fill + 2 copy moveto + 2 copy vpt 180 360 arc closepath fill + vpt 0 360 arc closepath} bind def +/C14 {BL [] 0 setdash 2 copy moveto + 2 copy vpt 90 360 arc closepath fill + vpt 0 360 arc} bind def +/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill + vpt 0 360 arc closepath} bind def +/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto + neg 0 rlineto closepath} bind def +/Square {dup Rec} bind def +/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def +/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def +/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def +/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def +/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def +/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def +/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill + exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def +/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def +/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill + 2 copy vpt Square fill Bsquare} bind def +/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def +/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def +/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill + Bsquare} bind def +/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill + Bsquare} bind def +/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def +/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill + 2 copy vpt Square fill Bsquare} bind def +/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill + 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def +/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def +/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def +/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def +/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def +/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def +/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def +/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def +/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def +/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def +/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def +/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def +/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def +/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def +/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def +/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def +/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def +/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def +/DiaE {stroke [] 0 setdash vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V closepath stroke} def +/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V closepath stroke} def +/TriUE {stroke [] 0 setdash vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V closepath stroke} def +/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V closepath stroke} def +/PentE {stroke [] 0 setdash gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + closepath stroke grestore} def +/CircE {stroke [] 0 setdash + hpt 0 360 arc stroke} def +/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def +/DiaW {stroke [] 0 setdash vpt add M + hpt neg vpt neg V hpt vpt neg V + hpt vpt V hpt neg vpt V Opaque stroke} def +/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M + 0 vpt2 neg V hpt2 0 V 0 vpt2 V + hpt2 neg 0 V Opaque stroke} def +/TriUW {stroke [] 0 setdash vpt 1.12 mul add M + hpt neg vpt -1.62 mul V + hpt 2 mul 0 V + hpt neg vpt 1.62 mul V Opaque stroke} def +/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M + hpt neg vpt 1.62 mul V + hpt 2 mul 0 V + hpt neg vpt -1.62 mul V Opaque stroke} def +/PentW {stroke [] 0 setdash gsave + translate 0 hpt M 4 {72 rotate 0 hpt L} repeat + Opaque stroke grestore} def +/CircW {stroke [] 0 setdash + hpt 0 360 arc Opaque stroke} def +/BoxFill {gsave Rec 1 setgray fill grestore} def +/Density { + /Fillden exch def + currentrgbcolor + /ColB exch def /ColG exch def /ColR exch def + /ColR ColR Fillden mul Fillden sub 1 add def + /ColG ColG Fillden mul Fillden sub 1 add def + /ColB ColB Fillden mul Fillden sub 1 add def + ColR ColG ColB setrgbcolor} def +/BoxColFill {gsave Rec PolyFill} def +/PolyFill {gsave Density fill grestore grestore} def +/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def +% +% PostScript Level 1 Pattern Fill routine for rectangles +% Usage: x y w h s a XX PatternFill +% x,y = lower left corner of box to be filled +% w,h = width and height of box +% a = angle in degrees between lines and x-axis +% XX = 0/1 for no/yes cross-hatch +% +/PatternFill {gsave /PFa [ 9 2 roll ] def + PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate + PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec + TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse + clip + currentlinewidth 0.5 mul setlinewidth + /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def + 0 0 M PFa 5 get rotate PFs -2 div dup translate + 0 1 PFs PFa 4 get div 1 add floor cvi + {PFa 4 get mul 0 M 0 PFs V} for + 0 PFa 6 get ne { + 0 1 PFs PFa 4 get div 1 add floor cvi + {PFa 4 get mul 0 2 1 roll M PFs 0 V} for + } if + stroke grestore} def +% +/languagelevel where + {pop languagelevel} {1} ifelse + 2 lt + {/InterpretLevel1 true def} + {/InterpretLevel1 Level1 def} + ifelse +% +% PostScript level 2 pattern fill definitions +% +/Level2PatternFill { +/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8} + bind def +/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} +>> matrix makepattern +/Pat1 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke + 0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke} +>> matrix makepattern +/Pat2 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L + 8 8 L 8 0 L 0 0 L fill} +>> matrix makepattern +/Pat3 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L + 0 12 M 12 0 L stroke} +>> matrix makepattern +/Pat4 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L + 0 -4 M 12 8 L stroke} +>> matrix makepattern +/Pat5 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L + 0 12 M 8 -4 L 4 12 M 10 0 L stroke} +>> matrix makepattern +/Pat6 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L + 0 -4 M 8 12 L 4 -4 M 10 8 L stroke} +>> matrix makepattern +/Pat7 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L + 12 0 M -4 8 L 12 4 M 0 10 L stroke} +>> matrix makepattern +/Pat8 exch def +<< Tile8x8 + /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L + -4 0 M 12 8 L -4 4 M 8 10 L stroke} +>> matrix makepattern +/Pat9 exch def +/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def +/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def +/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def +/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def +/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def +/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def +/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def +} def +% +% +%End of PostScript Level 2 code +% +/PatternBgnd { + TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse +} def +% +% Substitute for Level 2 pattern fill codes with +% grayscale if Level 2 support is not selected. +% +/Level1PatternFill { +/Pattern1 {0.250 Density} bind def +/Pattern2 {0.500 Density} bind def +/Pattern3 {0.750 Density} bind def +/Pattern4 {0.125 Density} bind def +/Pattern5 {0.375 Density} bind def +/Pattern6 {0.625 Density} bind def +/Pattern7 {0.875 Density} bind def +} def +% +% Now test for support of Level 2 code +% +Level1 {Level1PatternFill} {Level2PatternFill} ifelse +% +/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont +dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall +currentdict end definefont pop +Level1 SuppressPDFMark or +{} { +/SDict 10 dict def +systemdict /pdfmark known not { + userdict /pdfmark systemdict /cleartomark get put +} if +SDict begin [ + /Title (warp2.eps) + /Subject (gnuplot plot) + /Creator (gnuplot 4.6 patchlevel 3) + /Author (amothic) +% /Producer (gnuplot) +% /Keywords () + /CreationDate (Thu Feb 13 02:38:55 2014) + /DOCINFO pdfmark +end +} ifelse +end +%%EndProlog +%%Page: 1 1 +gnudict begin +gsave +doclip +50 50 translate +0.050 0.050 scale +0 setgray +newpath +(Helvetica) findfont 140 scalefont setfont +BackgroundColor 0 lt 3 1 roll 0 lt exch 0 lt or or not {BackgroundColor C 1.000 0 0 7200.00 5040.00 BoxColFill} if +1.000 UL +LTb +938 448 M +63 0 V +5946 0 R +-63 0 V +854 448 M +( 0) Rshow +1.000 UL +LTb +938 1185 M +63 0 V +5946 0 R +-63 0 V +-6030 0 R +( 50000) Rshow +1.000 UL +LTb +938 1922 M +63 0 V +5946 0 R +-63 0 V +-6030 0 R +( 100000) Rshow +1.000 UL +LTb +938 2660 M +63 0 V +5946 0 R +-63 0 V +-6030 0 R +( 150000) Rshow +1.000 UL +LTb +938 3397 M +63 0 V +5946 0 R +-63 0 V +-6030 0 R +( 200000) Rshow +1.000 UL +LTb +938 4134 M +63 0 V +5946 0 R +-63 0 V +-6030 0 R +( 250000) Rshow +1.000 UL +LTb +938 4871 M +63 0 V +5946 0 R +-63 0 V +-6030 0 R +( 300000) Rshow +1.000 UL +LTb +938 448 M +0 63 V +0 4360 R +0 -63 V +938 308 M +( 1) Cshow +1.000 UL +LTb +1796 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 2) Cshow +1.000 UL +LTb +2655 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 3) Cshow +1.000 UL +LTb +3513 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 4) Cshow +1.000 UL +LTb +4372 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 5) Cshow +1.000 UL +LTb +5230 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 6) Cshow +1.000 UL +LTb +6089 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 7) Cshow +1.000 UL +LTb +6947 448 M +0 63 V +0 4360 R +0 -63 V +0 -4500 R +( 8) Cshow +1.000 UL +LTb +1.000 UL +LTb +938 4871 N +938 448 L +6009 0 V +0 4423 V +-6009 0 V +Z stroke +LCb setrgbcolor +112 2659 M +currentpoint gsave translate -270 rotate 0 0 M +(req/s) Cshow +grestore +LTb +LCb setrgbcolor +3942 98 M +(number of cpus) Cshow +LTb +1.000 UP +1.000 UL +LTb +% Begin plot #1 +1.000 UP +1.000 UL +LT0 +1.00 0.00 0.00 C LCb setrgbcolor +6296 4738 M +(online) Rshow +LT0 +1.00 0.00 0.00 C 6380 4738 M +399 0 V +938 1097 M +858 197 V +859 19 V +858 28 V +859 -110 V +858 60 V +859 27 V +858 10 V +938 1097 Pls +1796 1294 Pls +2655 1313 Pls +3513 1341 Pls +4372 1231 Pls +5230 1291 Pls +6089 1318 Pls +6947 1328 Pls +6579 4738 Pls +% End plot #1 +% Begin plot #2 +1.000 UP +1.000 UL +LT1 +0.00 0.00 1.00 C LCb setrgbcolor +6296 4598 M +(offline) Rshow +LT1 +0.00 0.00 1.00 C 6380 4598 M +399 0 V +938 1104 M +858 756 V +859 656 V +858 583 V +859 175 V +858 731 V +859 -235 V +858 574 V +938 1104 Crs +1796 1860 Crs +2655 2516 Crs +3513 3099 Crs +4372 3274 Crs +5230 4005 Crs +6089 3770 Crs +6947 4344 Crs +6579 4598 Crs +% End plot #2 +1.000 UL +LTb +938 4871 N +938 448 L +6009 0 V +0 4423 V +-6009 0 V +Z stroke +1.000 UP +1.000 UL +LTb +stroke +grestore +end +showpage +%%Trailer +%%DocumentFonts: Helvetica diff -r d15c924e9089 -r 7c7afe38c9d6 paper/benchmark/warp/warp2.plt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/benchmark/warp/warp2.plt Thu Feb 13 03:02:48 2014 +0900 @@ -0,0 +1,9 @@ +set terminal postscript eps +set output "warp2.eps" + +set xrange [1:8] +set xlabel "number of cpus" +set ylabel "req/s" + +plot "online.dat" using 1:2 with linespoints linewidth 1 linecolor rgbcolor "red" title "online", "offline.dat" using 1:2 with linespoints linewidth 1 linecolor rgbcolor "blue" title "offline" + diff -r d15c924e9089 -r 7c7afe38c9d6 paper/conclusion.tex --- a/paper/conclusion.tex Wed Feb 12 21:08:01 2014 +0900 +++ b/paper/conclusion.tex Thu Feb 13 03:02:48 2014 +0900 @@ -8,7 +8,7 @@ 実装において, Haskellの表現力とコンパイル時に多くのエラーを捕まえるという特徴は, 開発期間およびコード行数の短縮に繋がった. また, 型安全により実行時に型エラーによってプログラムが終了するといったことがない. -読み込みに関して 12 コアで実行した場合, 1 コアで実行した場合と比較して, 10.77 倍 という性能向上率が確認でき, マルチコアプロセッサの性能を引き出すことができた. +読み込みに関して 12 コアで実行した場合, 1 コアで実行した場合と比較して, 10.37 倍 という性能向上率が確認でき, マルチコアプロセッサの性能を引き出すことができた. また, Web 掲示板サービスを開発し, 既存の Java の非破壊的木構造データベースを用いた掲示板実装との比較をおこない, 読み込みで 3.25 倍, 書き込みで 3.78 倍の性能が確認できた. \section{今後の課題} diff -r d15c924e9089 -r 7c7afe38c9d6 paper/master_paper.pdf Binary file paper/master_paper.pdf has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/bbs.png Binary file slides/images/bbs.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/jungle_type.png Binary file slides/images/jungle_type.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/node_component.png Binary file slides/images/node_component.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/read.png Binary file slides/images/read.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/request.png Binary file slides/images/request.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/warp.png Binary file slides/images/warp.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/images/write.png Binary file slides/images/write.png has changed diff -r d15c924e9089 -r 7c7afe38c9d6 slides/master.html --- a/slides/master.html Wed Feb 12 21:08:01 2014 +0900 +++ b/slides/master.html Thu Feb 13 03:02:48 2014 +0900 @@ -44,7 +44,7 @@

Daichi TOMA
- Feb 4, 2014 + Feb 12, 2014

@@ -53,15 +53,16 @@ 研究概要

- Haskell を用いて並列データベースを実装した。 + Haskell を用いて並列データベースを実装した

- 読み込みに関して 12 コアで実行した場合、10.77 倍 という性能向上率が確認できた。 + 読み込みに関して 12 コアで実行した場合、10.37 倍 という性能向上率が確認できた

- また、Web 掲示板サービスを開発し、Java と比較して読み込みで 1.87 倍、書き込みで 2.3倍の性能が確認できた。 + また、Web 掲示板サービスを開発し、Java と比較して読み込みで 3.25 倍、書き込みで 3.78 倍の性能差が確認できた

+

研究背景 @@ -73,27 +74,23 @@ Haskell は型検査でバッファオーバーフローや、クロスサイトスクリプティング、SQL インジェクションを防げる

- Haskell を用いてデータベースと Web サービスの開発を行う + Haskell を用いることで信頼性の高いデータベースとWebサービスを開発できる

- Haskell + 型による区別

- Haskellは純粋関数型プログラミング言語 + Haskellは、全てに型がある

- 純粋とは、引数が同じならば関数が必ず同じ値を返す + 文字列やHTMLを別の型として扱う

- -
-fib :: Int −> Int
-fib 0 = 0
-fib 1 = 1
-fib n = fib (n-2) + fib (n-1)
-
+

+ 入力として受け取った文字列が、HTML型に自動変換されたりせず、脆弱性が勝手に入り込んだりしない +

@@ -110,13 +107,8 @@ コンパイル時にエラーになる

-abc = 'a' : [1,2,3]
-cde =  1  : ['a','b','c']
-
- -
--- リスト型の定義
-data [] a = [] | a : [a]
+abc = 'a' : [1,2,3] -- error
+cde =  1  : ['a','b','c'] -- error
 
@@ -125,114 +117,62 @@ 型推論

- Haskell が型を推論してくれる + 型エラーを検出するために全ての式や関数に型を書いていくのは大変

-
-getChildren node path = elems (children (getNode node path))
-

- getChildren は、Node と Path を受け取って Node のリストを返すことがわかる + Haskell は 型を推論してくれる

-
-*Jungle> :type getChildren
-getChildren :: Node -> Path -> [Node]
-
+ + +
+

+ 型推論 +

- 他の型の情報を利用して推論できる + 前提として関数に以下のような型が定義されている

 getNode :: Node -> Path -> Node
 elems :: Map k a -> [a]
 children :: Node -> Map Int Node
 
-
- -
-

- モナド -

- モナドを使うことで文脈を保ったまま関数を繋いでいくことができる -

-

- Maybe モナドを用いて説明する -

-

- Maybe 型は、失敗する可能性を扱うデータ型である + 新しくgetChildrenという関数を定義するとき型を自動で導出できる

-data Maybe a = Nothing | Just a
+getChildren node path = elems (children (getNode node path))
+
+

+ Haskell が推論した型を確認する +

+
+*Jungle> :type getChildren
+getChildren :: Node -> Path -> [Node]
 

- モナド - 型クラス + 実用的なデータベースの開発

- Maybe 型は、モナド型クラスのインスタンスである。 -

-

- 型クラスは、オブジェクト指向のクラスとは異なる。 + 現在、CPU はマルチコア化がすすんでいる

- 型の振る舞いを定義するもので、今回は Maybe 型はモナドとして振る舞えるという意味になる。 + 実用的なデータベースとするためにはマルチコアに対応させる必要性がある

-
-instance Monad Maybe where
-    return x = Just x
-    Nothing >>= f = Nothing
-    Just x >>= f  = f x
-

- モナドとして振る舞うためには2つの関数を定義する。 - - return と、>>= (bind)である。 + 並列に処理できればマルチコアで性能が出る

- モナド - 関数を繋ぐ + Haskell の並列実行

- 失敗するかもしれないという文脈を保ったまま関数を繋ぐ + Haskell で並列実行するにはどうするか

-
-up 4 = Nothing
-up n = Just (n + 1)
-
-down 0 = Nothing 
-down n = Just (n - 1)
-
-
-return 3 >>= down >>= down >>= up >>= up
-
-
-instance Monad Maybe where
-    return x = Just x
-    Nothing >>= f = Nothing
-    Just x >>= f  = f x
-
-
- -
-

- モナドを使わないで同じことをする -

-
-return 3 >>= down >>= down >>= up >>= up
-
-
-updown :: Maybe Int
-updown = case down 3 of
-            Nothing -> Nothing
-            Just place1 -> case down place1 of
-                    Nothing -> Nothing
-                    Just place2 -> case up place2 of
-                            Nothing -> Nothing
-                            Just place3 -> up place3
-
@@ -240,7 +180,7 @@ 非破壊的木構造

- データベースを線形に性能向上させたければ、各コアからデータに同時にアクセスできるようにし並列度を高める + マルチコア上で、データベースの性能向上をさせるためには、各コアからデータに同時にアクセスできるようにする

非破壊的木構造という手法を用いる。 @@ -261,163 +201,156 @@ 非破壊的木構造 - ルートノード

- どの木構造が最新なのかを表す情報 + 非破壊的木構造の並列実行のネックとなるものがルートノード +

+

+ ルートノードは、どの木構造が最新なのかを表す情報

状態を持つのはここだけで、並列度を高めるにはルートノードの設計が重要

- +

- データベースの設計 - 並列度を高めるために -

-

- できるだけルートノードに触る範囲を狭くする -

-

- ルートノードを更新する関数と、編集する関数を切り分ける -

-
- -
-

Haskell でのルートノードの管理

ソフトウェア・トランザクショナル・メモリ (STM) を使う

- STM は、排他制御を行わずに共有データを扱える -

-

- STM は、他のスレッドによる変更を考慮せずに共有データを変更する + STM は、ノンブロッキングで共有データを扱える

- 変更をトランザクションとしてコミットする時に以下のことがひとつだけ起こる + 共有データの変更は以下の様に行われる

-

- Jungle のデータ型 + STM のメリット

- Jungle は、非破壊的木構造を扱う並列データベース -

-
--- Jungle のデータ型
-data Jungle = Jungle (TVar (Map String Tree))
-
--- Tree のデータ型
-data Tree = Tree (TVar Node) String
-
--- Node のデータ型
-data Node = Node (Map Int Node) (Map String ByteString)
-
-

- TVarがついてるのはSTMを使ってる変数 + 共有データにアクセスする時に待ちがない

- Map は連想配列 + 読み込みは他の変更を気にせず並列に行える

- Jungle の実装 + 非破壊的木構造データベース Jungle

- Jungle は複数の Tree を持っている。 - Tree には名前がついており、最新のルートノードを持っている。 + 非破壊的木構造を扱うデータベース Jungle を開発した +

+

+ Jungle の基本的な使い方 +

+ +
+ +
+

+ 木構造を保持する Jungle の作成 +

+
+data Jungle = Jungle (TVar (Map String Tree))
+
+

+ TVarがついているのはSTMを使っている変数 +

+

+ 各スレッドから新しく木を作ったりできるように木構造の保持にもSTMを使っている +

+

+ Jungle は複数の Tree を名前で管理する

- +
-
+

- 状態を扱う関数 + Jungle に新しい木を作成

-createJungle :: IO Jungle
-createTree :: Jungle -> String -> IO ()
+data Tree = Tree (TVar Node) String
+
+

+ Tree は最新のルートノードの情報と木の名前を持っている +

+
+
+
+ +
+
+ +
+

+ 木から最新のルートノードを取ってきて、データを参照する +

+

+ 木から最新のルートノードを取ってくるにはgetRootNodeという関数を使う +

+
 getRootNode :: Jungle -> String -> IO Node
+
+

+ Jungleと木の名前を渡すと最新のルートノードが返ってくる +

+
+ +
+

+ ノード +

+

+ Jungle で最も基本的な構成要素 +

+

+ Jungle の参照や変更の関数は全てノードに対して行う +

+
+data Node = Node (Map Int Node) (Map String ByteString)
+
+
+ +
+
+ +
+

+ ノードを編集し、木の最新のルートノードを更新する +

+

+ updateRootNodeやupdateRootNodeWithで更新できる +

+
 updateRootNode :: Jungle -> String -> Node -> IO ()
 updateRootNodeWith :: (Node -> Node) -> Jungle -> String -> IO ()
 

- IO が付いているものは何かしらの状態の変更を行う関数である。 -

-

- この関数の型の -> で繋がっているものは複数の引数を取ることを表している。 -

-

- 実際にはHaskellの関数はカリー化されているため、全ての関数は一度に一つの引数だけを取る。 - 複数の引数を取るようにみえる関数は、実際には1つの引数を取り、その次の引数を受け取る関数を返す。 + updateRootNodeには編集したNodeを渡すことで木の最新のルートノードを更新できる

- createJungle は Jungle の作成
- createTree は、Jungle と 木の名前を受け取って、木を作成する
- getRootNode は、Jungle と 木の名前を受け取って、ルートノードを返す
- updateRootNode は、Jungle と 木の名前と Node を受け取ってルートノードを更新する。
- updateRootNodeWith は、Node を編集する関数(Node -> Node)と Jungle と 木の名前を取って、ルートノードに関数を適用して更新する。
-

-
- -
-

- 木構造の編集 -

-
-addNewChildAt :: Node -> Path -> Node
-deleteChildAt :: Node -> Path -> Position -> Node
-putAttribute :: Node -> Path -> String -> B.ByteString -> Node
-deleteAttribute :: Node -> Path -> String -> Node
-
- -

- 状態の変更は行わない。 + updateRootNodeWithにはNodeを編集する関数を渡すことで木の最新のルートノードを更新できる

-

- addNewChildAt は、指定された Path の Node に子を追加する
- deleteChildAt は、指定された Path の Node の Position の子を削除する
- putAttribute は、指定された Path の Node に キーと値を追加する
- deleteAttribute は、指定された Path の Node のキーにあてはまる値を削除する
-

- -
-
-

- 木構造の参照 -

-
-getAttributes :: Node -> Path -> String -> Maybe B.ByteString
-getChildren :: Node -> Path -> [Node]
-assocsChildren :: Node -> Path -> [(Int, Node)]
-assocs :: Node -> Path ->  [(String, B.ByteString)]
-numOfChild :: Node -> Path -> Int
-currentChild :: Node -> Path -> Maybe Node
-
- -

- getAttributes は、指定された Path の Node に存在する属性を キー を用いて参照できる
- getChildren は、指定されたPath のNode が持つ全ての子を Node のリストとして返す
- assocsChildren は、指定された Path の Node が持つ全ての子を Position とのタプルにし、そのペアのリストを返す
- assocsAttribute は、指定された Path の Node が持つ全ての属性を、キーと値のペアとし、そのペアのリストを返す
- numOfChild では、指定された Path の Node が持つ子どもの数を取得できる
- currentChild では、指定された Path の Node が持つ最新の子を取得できる
-

-
@@ -428,8 +361,10 @@ Jungle がマルチコアプロセッサで性能が出るのか、実用的なWebサービスが提供できるのか確認する

- 性能の計測に用いるサーバの仕様
- ハイパースレッディングで24コアまで使える + 性能の計測に用いるサーバの仕様 +

+ ハイパースレッディングで24コアまで使える
+ ハイパースレッディングはおよそ20%程度クロックあたりの性能が向上する

@@ -450,71 +385,110 @@ - +
OSFedora 14Fedora 19
+
+

+ Haskell コンパイラ +

+

+ Haskell のコンパイラには The Glasgow Haskell Compiler (GHC) を利用する +

+

+ 現在の GHC の安定版 7.6.3 は並列時にIOマネージャーがスケールしないという問題がある +

+

+ リリース候補版である 7.8 を用いる +

+
+ +
+

+ 親和性機能 +

+

+ 親和性機能とは OS スレッドをCPUコアに固定する機能のこと +

+

+ 並列実行時の性能が向上するため性能計測で利用する +

+

+ Haskell は実行時に -qa オプションを使うこと親和性機能を使うように指示できる +

+
+

- 性能計測 - 読み込みの計測結果 + 読み込みの性能計測

木構造の読み込みにかかる時間を計測する

- 12 スレッドで実行時に 10.77 倍の性能向上 + 12 スレッドで親和性機能を使って実行した場合 10.37 倍の性能向上

- ハイパースレッディングは遅くなったりと安定しない + 親和性機能を使って24スレッドで実行すると実行時間が大幅に伸びる

- + + - + + - + + - + + - + + - + + - + + - + + - + +
CPU数実行時間親和性機能なし親和性機能あり
159.77 s60.95 s61.00 s
233.36 s30.83 s33.95 s
415.63 s15.49 s16.10 s
88.10 s10.31 s8.79 s
125.55 s8.49 s5.88 s
165.65 s5.82 s5.81 s
205.23 s6.54 s5.48 s
245.77 s8.21 s125.09 s

-
+

- 性能計測 - 読み込みの計測結果 + 読み込みの性能計測

- ハイパースレッディングは安定しないため、12 スレッドまでの性能向上率 + 親和性機能を使った場合、実コアの12スレッドまでほぼ線形にスケールする

@@ -523,64 +497,74 @@

- 性能計測 - 書き込みの計測結果 + 書き込みの性能計測

木構造の書き込みにかかる時間を計測する

- 2 スレッドで 1.55 倍の性能向上
- 12 スレッドで実行時に 3.86 倍の性能向上 -

-

- ハイパースレッディングは12スレッド以降遅くなっている + 12 スレッドで親和性機能を使って実行した場合 3.82 倍の性能向上

- + + - + + - + + - + + - + + - + + - + + - + + - + +
CPU数実行時間親和性機能なし親和性機能あり
152.68 s49.70 s49.61 s
233.92 s27.77 s30.76 s
420.11 s18.06 s18.05 s
815.31 s16.66 s12.50 s
1213.62 s15.62 s12.96 s
1614.92 s14.91 s13.11 s
2018.62 s15.31 s13.84 s
2416.63 s18.11 s71.66 s

-
+

- 性能計測 - 書き込みの計測結果 + 書き込みの性能計測

-
+

+ 4 倍程度で性能向上が頭打ちになっている +

+

+ 同時に書き込みがあった場合、STMが処理をやり直すため並列度が下がる +

@@ -591,153 +575,131 @@ 考察

- 書き込みの性能向上率が低い -

-

- 木を登録する際、他のスレッドから登録があった場合、ソフトウェア・トランザクショナル・メモリが処理をやり直すため遅いと考えられる。 + 読み込みが高速

- 書き込みより読み込みが多用されるシステムに向いている。 -

-
- -
-

- 性能計測 - Webサービスに組み込んでの性能評価 -

-

- Haskell の HTTP サーバ Warp と組み合わせて Web掲示板サービスを開発する。 -

-

- weighttpを用いて掲示板に読み込みと書き込みで負荷をかける。リクエストの総数は100万 -

-

- Warp は、ハイパースレッディングで明らかに遅くなるので、12コアまでの計測とする。 + 書き込みより読み込みが多用されるシステムに向いている

- 性能計測 - Webサービスに組み込んでの性能評価 読み込み + Webサービスに組み込んでの性能計測

- 読み込み + Haskell の HTTP サーバ Warp と組み合わせて Web掲示板サービスを開発する +

+

+ 測定ツール weighttp を用いて掲示板に読み込みと書き込みで負荷をかける。

- 12 スレッド時に 2.14 倍 + Warp は、ハイパースレッディングで明らかに遅くなるので、使わない

- - - - - - - - - - - - - - - - - - - - - - - - - -
CPU数実行時間
160.72 s
237.74 s
428.97 s
827.73 s
1228.33 s
+
+ +
+

+ ネットワークのボトルネック +

+

+ ネットワークのボトルネックが大きい +

+

+ 並列環境でどのようにスケールするか計測したいため、ネットワークを介さずに性能計測を行う +

+
+
+ +

- 性能計測 - Webサービスに組み込んでの性能評価 書き込み + 実験環境

- 書き込み + 3 コアを測定ツール weighttp に使い、 + 8 コアを Web 掲示板サービスに使う +

+
+
+ +
+
+ +
+

+ Webサービスに組み込んでの性能計測 +

+

+ 読み込みと書き込みの実験結果

- 12 スレッド時に 1.65 倍 + 1秒間あたりどれだけリクエストを捌けるかという指標で比較 + 大きければ大きいほど性能が良い +

+

+ 8 スレッドで実行時、読み込みは 6.18 倍、書き込みは3.93倍の性能向上

- + + - + + - + + - + + + + + + + - - - - - + +
CPU数実行時間読み込み書き込み
154.16 s22,624 req/s28,552 req/s
236.71 s43,083 req/s53,765 req/s
431.74 s92,548 req/s98,691 req/s
6119,310 req/s99,009 req/s
831.58 s
1232.68 s139,965 req/s112,212 req/s
-
+

- Warp の問題 + Webサービスに組み込んでの性能計測

- Warp がボトルネックとなってしまっている。 - Warp は現状あまり並列化効果がでていない。 -

-

- アクセスした際に、"hello, world" という文字列を返すだけのプログラムを作成し計測する。 -

-

- Jungle を組み込んだ時と比較して、読み込みの場合はほとんど差がない。 + Jungle 単体での実験結果と同じで、読み込みのほうがスケールする

- - - - - - - - - - - - - - - - - - - - - - - - - -
CPU数実行時間
149.28 s
235.45 s
425.70 s
827.90 s
1229.23 s
+
+ +

- 性能計測 - Java との比較 + Java との比較

+

+ HaskellとJavaで同様のWeb掲示板サービスを用意する +

+

+ 実環境を想定して、ブレードサーバ2台用意し、ネットワークを介して負荷をかける +

+

+ 100 万リクエストを処理するのにかかる時間を計測 +

@@ -747,65 +709,42 @@ - + - +
読み込み28.33 s16.31 s 53.13 s
書き込み32.68 s20.17 s 76.4 s

- 読み込みで 1.87 倍、書き込みで 2.3 倍の性能差が出ている + 読み込みで 3.25 倍、書き込みで 3.78 倍の性能差

- 書き込みが読み込みより性能差が出ている理由として遅延評価が考えられる。 - Haskell の遅延評価は必要でなければ計算しないため、例えば木構造への書き込みが多い時に必要のない木は計算しないなどを行うことができる。 + Haskell は実用的なWebサービスを開発できる

- 性能計測 - 書き込みと読み込みを同時に行った場合 + Java との比較 - 生産性

-

- 書き込みごとに毎回読み込みを挟むことで、遅延評価ではなく即時評価させる。 -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
CPU数実行時間
1141.40 s
270.87 s
454.32 s
855.13 s
1258.60 s
-

- 結果が明らかに遅くなっている。 - 12 スレッドで実行した際、 まだ Java より速いが性能差は、1.30 倍である。 + 生産性の面からも Java との比較を行う

- シングルスレッドで実行した場合と比較した時、12 スレッドで 2.40 倍の性能向上が見られる。 + Haskell 版 Jungle は 284 行、 + Java 版 Jungle は 3,390 行 +

+

+ 実装が 1/12 程度のサイズとなっている +

+

+ 再帰的なデータ型の定義を言語としてサポートしていることや、関数の再利用が行いやすいことが要因 +

+

+ 同じ機能を実装する場合でも、Haskell は Java と比較してコード行数が短くなる

@@ -817,10 +756,10 @@ 純粋関数型言語 Haskell を用いて並列データベースの実装をおこなった

- 読み込みに関して 12 コアで実行した場合、10.77 倍 という性能向上率が確認できた + 読み込みに関して 12 コアで実行した場合、10.37 倍 という性能向上率が確認できた

- また、Web 掲示板サービスを開発し、Java と比較して読み込みで 1.87 倍、書き込みで 2.3倍の性能が確認できた + また、Web 掲示板サービスを開発し、Java と比較して読み込みで 3.25 倍、書き込みで 3.78 倍の性能が確認できた

@@ -839,6 +778,5 @@

-