ฉันเชื่อว่าทุกคนรู้ว่า JSON คืออะไร หากคุณไม่รู้มันก็ออกมาจริงๆ GOOGLE. ฉันจะไม่แนะนำอะไรที่นี่
ฉันเดาว่าทุกคนไม่ค่อยได้ยินเกี่ยวกับ Protobuffer แต่ถ้าทำโดย Google ฉันเชื่อว่าทุกคนจะสนใจลอง ท้ายที่สุด Google Exports ส่วนใหญ่เป็นผลิตภัณฑ์คุณภาพสูง
Protobuffer เป็นโปรโตคอลการส่งสัญญาณที่คล้ายกับ JSON ในความเป็นจริงมันไม่สามารถกล่าวได้ว่าเป็นโปรโตคอลมันเป็นเพียงการส่งข้อมูล
ดังนั้นความแตกต่างระหว่างมันกับ JSON คืออะไร?
ข้ามภาษานี่เป็นหนึ่งในข้อดีของมัน มันมาพร้อมกับคอมไพเลอร์, โปรโตคซึ่งจำเป็นต้องรวบรวมกับมันเท่านั้นและสามารถรวบรวมเป็นรหัส Java, Python และ C ++ มีเพียงสามคนนี้ในขณะนี้ดังนั้นอย่าคิดถึงคนอื่น ๆ ในขณะนี้และจากนั้นคุณสามารถใช้โดยตรงโดยไม่ต้องเขียนรหัสอื่น ๆ แม้แต่คนที่แยกวิเคราะห์ก็มากับพวกเขาแล้ว JSON เป็นภาษาข้ามภาษาแน่นอน แต่ข้ามภาษานี้ใช้รหัสการเขียน
หากคุณต้องการทราบข้อมูลเพิ่มเติมคุณสามารถตรวจสอบได้:
https://developers.google.com/protocol-buffers/docs/overview
โอเคโดยไม่ต้องกังวลใจเพิ่มเติมลองมาดูกันว่าทำไมเราต้องเปรียบเทียบ Protobuffer (ต่อไปนี้เรียกว่า GPB) และ JSON
1. เนื่องจาก JSON มีรูปแบบที่แน่นอนและมีอยู่ในตัวละครจึงยังมีที่ว่างสำหรับการบีบอัดจำนวนข้อมูล เมื่อจำนวนข้อมูลขนาดใหญ่บน GPB นั้นเล็กกว่าของ JSON มากเราสามารถดูตัวอย่างด้านล่างได้
2. ความแตกต่างของประสิทธิภาพระหว่างไลบรารี JSON มีขนาดค่อนข้างใหญ่และมีช่องว่างประมาณ 5-10 ระหว่างห้องสมุดแจ็คสันและ GSON (สิ่งนี้ได้รับการทดสอบเพียงครั้งเดียวหากมีข้อผิดพลาดใด ๆ โปรดตบเบา ๆ ) GPB ต้องการเพียงหนึ่งเดียวและไม่มีความแตกต่างระหว่างห้องสมุดหลายห้องที่เรียกว่า แน่นอนจุดนี้เป็นเพียงการสร้างขึ้นสำหรับตัวเลขและสามารถเพิกเฉยได้
พูดคุยราคาถูกเพียงแค่แสดงรหัสให้ฉันดู
ในโลกการเขียนโปรแกรมรหัสเป็นกษัตริย์เสมอดังนั้นลองไปที่รหัส
ก่อนอัปโหลดรหัสคุณต้องดาวน์โหลด protobuffer ก่อนที่นี่:
https://github.com/google/protobuf
1. ก่อนอื่น GPB ต้องมีไฟล์ที่มีคำจำกัดความของคลาสที่คล้ายกันเรียกว่าไฟล์โปรโต
มาเป็นตัวอย่างของนักเรียนและครูเพื่อทำตัวอย่าง:
เรามีสองไฟล์ต่อไปนี้: student.proto
ตัวเลือก java_package = "com.shun"; ตัวเลือก java_outer_classname = "StudentProto"; นักเรียนข้อความ {จำเป็นต้องใช้ int32 id = 1; ชื่อสตริงเสริม = 2; ทางเลือก int32 อายุ = 3; } </span> ครู. โปรโต
นำเข้า "student.proto"; ตัวเลือก java_package = "com.shun"; ตัวเลือก java_outer_classname = "TeacherProto"; ครูข้อความ {จำเป็นต้องใช้ int32 id = 1; ชื่อสตริงเสริม = 2; นักเรียนซ้ำ ๆ student_list = 3; } </span> ที่นี่เราพบกับสิ่งแปลก ๆ :
นำเข้า, int32, ซ้ำ, จำเป็น, ตัวเลือก, ตัวเลือก ฯลฯ
1) การนำเข้าหมายถึงการนำเข้าไฟล์โปรโตอื่น ๆ
2) จำเป็นและเป็นตัวเลือกระบุว่าฟิลด์เป็นตัวเลือกหรือไม่ สิ่งนี้จะกำหนดว่าการประมวลผลจะทำอย่างไรโดย protobuffer หากฟิลด์มีค่าหรือไม่ หากจำเป็นต้องทำเครื่องหมาย แต่เมื่อการประมวลผลฟิลด์จะไม่ผ่านค่าจะมีการรายงานข้อผิดพลาด หากมีการทำเครื่องหมายทางเลือกจะไม่มีการส่งค่าจะไม่มีปัญหา
3) ฉันเชื่อว่าคุณสามารถเข้าใจซ้ำได้ซึ่งหมายความว่าจะทำซ้ำหรือไม่มันคล้ายกับรายการใน Java
4) ข้อความเทียบเท่ากับชั้นเรียน
5) ตัวเลือกแสดงถึงตัวเลือกโดยที่ Java_Package แสดงชื่อแพ็คเกจนั่นคือชื่อแพ็คเกจที่ใช้เมื่อสร้างรหัส Java java_outer_classname เป็นชื่อคลาส โปรดทราบว่าชื่อคลาสนี้ไม่สามารถเหมือนกับชื่อคลาสในข้อความด้านล่าง
สำหรับตัวเลือกอื่น ๆ และประเภทที่เกี่ยวข้องกรุณาเยี่ยมชมเอกสารอย่างเป็นทางการ
2. ด้วยเอกสารเหล่านี้เราจะทำอย่างไร?
จำคอมไพเลอร์ที่ดาวน์โหลดด้านบน เปิดเครื่องซิปและเราได้รับ protoc.exe แน่นอนว่านี่เป็นไปตาม Windows ฉันไม่ได้ทำระบบอื่น หากคุณสนใจคุณสามารถลองใช้
เพิ่มไปยังเส้นทาง (ง่ายต่อการเพิ่มหรือไม่มันไม่สะดวก) จากนั้นคุณสามารถสร้างไฟล์คลาสที่เราต้องการผ่านไฟล์ด้านบน
protoc -java_out = path เพื่อจัดเก็บซอร์สโค้ด -proto_path = path ไปยังไฟล์ proto proto ไฟล์เฉพาะ
-proto_path ระบุเส้นทางโฟลเดอร์ของไฟล์ proto ไม่ใช่ไฟล์เดียวส่วนใหญ่จะใช้สำหรับการค้นหาไฟล์นำเข้าและสามารถละเว้นได้
ถ้าฉันต้องการใส่ซอร์สโค้ดใน d:/protobuffervsjson/src ไฟล์โปรโตของฉันจะถูกเก็บไว้ใน d:/protofiles
คำสั่งรวบรวมของฉันคือ:
protoc -java_out = d:/protobuffervsjson/src d: /protofiles/teacher.proto d: /protofiles/student.proto
โปรดทราบว่าในไฟล์ล่าสุดที่นี่เราจำเป็นต้องระบุไฟล์ทั้งหมดที่ต้องรวบรวม
หลังจากการรวบรวมคุณสามารถเห็นไฟล์ที่สร้างขึ้น
รหัสไม่ได้โพสต์มากเกินไป คุณสามารถดูเป็นการส่วนตัว มีผู้สร้างจำนวนมากในรหัส ฉันเชื่อว่าคุณจะรู้ว่ามันเป็นโหมดผู้สร้างได้อย่างรวดเร็ว
ในเวลานี้คุณสามารถวางรหัสลงในโครงการของคุณและแน่นอนว่ามีข้อผิดพลาดมากมาย
จำซอร์สโค้ดที่เราดาวน์โหลดก่อนหน้านี้ได้หรือไม่? เปิดเครื่องซิปอย่าไร้ความปรานี จากนั้นค้นหา SRC/Main/Java/เพื่อคัดลอกหนึ่งในโครงการของคุณ แน่นอนคุณสามารถรวบรวมมดหรือ maven ได้ แต่ฉันไม่คุ้นเคยกับสองสิ่งนี้ดังนั้นฉันจะไม่น่าเกลียดอีกต่อไป ฉันยังคงคุ้นเคยกับการคัดลอกโดยตรงไปยังโครงการ
ข้อผิดพลาดของรหัสฮ่าฮ่าปกติ ด้วยเหตุผลบางอย่าง Google ยืนยันที่จะออกจากหลุมดังกล่าวสำหรับเรา
กลับไปที่ /java ในไดเรกทอรี protobuffer และดู readme.txt และค้นหาประโยค:
หลังจากดูแล้วฉันรู้สึกว่ารหัสนี้จะแปลก ๆ ราวกับว่ามันผิด อย่างไรก็ตามฉันไม่ได้ดำเนินการและคำสั่งของฉันคือ:
<span style = "ตัวอักษรขนาด: 16px;"> protoc-java_out = หรือเส้นทางของไฟล์โปรโตที่วางรหัส (นี่คือเส้นทางของไฟล์ descriptor.proto) </span>
หลังจากดำเนินการเราจะเห็นว่าไม่มีข้อผิดพลาดในรหัส
3. ขั้นตอนต่อไปคือการทดสอบแน่นอน
ลองดำเนินการทดสอบการเขียน GPB ก่อน:
แพ็คเกจ com.shun.test; นำเข้า Java.io.FileOutputStream; นำเข้า java.io.ioException; นำเข้า java.util.arraylist; นำเข้า java.util.list; นำเข้า com.shun.studentproto.student; นำเข้า com.shun.teacherproto.teacher; ProtowRitetest ระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (String [] args) พ่น IOException {student.builder quuilder = student.newbuilder (); Stubuilder.setage (25); Stubuilder.setid (11); Stubuilder.setName ("Shun"); // สร้างรายการรายการ <student> quantuilderList = new ArrayList <Tudent> (); ubuilderlist.add (ubuilder.build ()); ครู. builder teabuilder = อาจารย์ newbuilder (); teabuilder.setid (1); teabuilder.setName ("testtea"); Teabuilder.AddallstudentList (ubuilderlist); // เขียน gpb ไปยังไฟล์ fileOutputStream fos = ใหม่ fileOutputStream ("c: //users//shun//desktop//test//test.protoout"); teabuilder.build (). writeto (fos); fos.close (); }} </span> ลองดูที่ไฟล์ถ้าไม่มีอะไรเกิดขึ้นที่ไม่คาดคิดก็ควรจะถูกสร้างขึ้น
หลังจากสร้างขึ้นเราต้องอ่านมันกลับ
แพ็คเกจ com.shun.test; นำเข้า Java.io.FileInputStream; นำเข้า java.io.filenotfoundException; นำเข้า java.io.ioException; นำเข้า com.shun.studentproto.student; นำเข้า com.shun.teacherproto.teacher; ProtoreAdtest ระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (String [] args) พ่น filenotfoundexception, ioexception {ครูครู = อาจารย์. parsefrom (ใหม่ fileInputStream ("c: //users//shun//desktop//test/test.protoout")); System.out.println ("ID ครู:" + Teacher.getId () + ", ชื่อ:" + Teacher.getName ()); สำหรับ (Student Stu: Teacher.getStudentListList ()) {system.out.println ("รหัสนักเรียน:" + stu.getId () + ", ชื่อ:" + stu.getName () + ", อายุ:" + stu.getage ()); }}}} </span> รหัสนั้นง่ายมากเนื่องจากรหัสทั้งหมดที่สร้างโดย GPB นั้นทำสำหรับเรา
ข้างต้นรู้การใช้งานขั้นพื้นฐาน เราจะมุ่งเน้นไปที่ความแตกต่างระหว่างขนาดไฟล์ GPB และ JSON ที่สร้างขึ้น ฉันจะไม่โพสต์รหัสรายละเอียดของ JSON ที่นี่ ฉันจะโพสต์ตัวอย่างในภายหลัง หากคุณสนใจคุณสามารถดาวน์โหลดได้
ที่นี่เราใช้ GSON เพื่อแยกวิเคราะห์ JSON ต่อไปนี้เป็นเพียงรหัสสำหรับการแปลงวัตถุเป็น JSON และเขียนไฟล์:
ฉันจะไม่เขียนคำจำกัดความพื้นฐานของนักเรียนและครูทั้งสองชั้นเรียนเพียงทำตามที่คุณต้องการรหัสมีดังนี้:
แพ็คเกจ com.shun.test; นำเข้า java.io.filewriter; นำเข้า java.io.ioException; นำเข้า java.util.arraylist; นำเข้า java.util.list; นำเข้า com.google.gson.gson; นำเข้า com.shun.student; นำเข้า com.shun.teacher; ระดับสาธารณะ GSONWRITETEST {โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่น IOException {นักเรียน stu = นักเรียนใหม่ (); Stu.setage (25); stu.setid (22); Stu.setName ("Shun"); รายการ <student> stulist = new ArrayList <Tudent> (); Stulist.add (Stu); ครูครู = ครูใหม่ (); ครู Setid (22); อาจารย์. setName ("Shun"); ครู SetStulist (Stulist); String result = new gson (). tojson (ครู); FileWriter fw = ใหม่ fileWriter ("C: // ผู้ใช้ // shun/desktop // test // json"); fw.write (ผลลัพธ์); fw.close (); }} </span> ต่อไปเราป้อนรหัสทดสอบจริงของเราอย่างเป็นทางการ ในตอนแรกเราเพิ่งใส่วัตถุในรายการ ต่อไปเราทดสอบขนาดไฟล์ที่สร้างโดย GPB และ JSON
ปรับปรุงรหัส GPB ก่อนหน้าให้สร้างจำนวนรายการที่แตกต่างกันและสร้างไฟล์ใหม่:
แพ็คเกจ com.shun.test; นำเข้า Java.io.FileOutputStream; นำเข้า java.io.ioException; นำเข้า java.util.arraylist; นำเข้า java.util.list; นำเข้า com.shun.studentproto.student; นำเข้า com.shun.teacherproto.teacher; ProtowRitetest ระดับสาธารณะ {สาธารณะคงที่ขนาดสุดท้าย int = 100; โมฆะสาธารณะคงที่หลัก (สตริง [] args) พ่น IOException {// รายการรายการรายการ <student> quantuilderList = new ArrayList <Tudent> (); สำหรับ (int i = 0; i <size; i ++) {student.builder stubuilder = student.newbuilder (); Stubuilder.setage (25); Stubuilder.setid (11); Stubuilder.setName ("Shun"); ubuilderlist.add (ubuilder.build ()); } teacher.builder teabuilder = ครู newbuilder (); teabuilder.setid (1); teabuilder.setName ("testtea"); Teabuilder.AddallstudentList (ubuilderlist); // เขียน gpb ไปยังไฟล์ fileOutputStream fos = ใหม่ fileOutputStream ("c: // ผู้ใช้ // shun // เดสก์ท็อป // test // proto-" + size); teabuilder.build (). writeto (fos); fos.close (); }} </span> ขนาดที่นี่เปลี่ยนเป็นหมายเลขทดสอบที่เรากล่าวไว้ข้างต้นและคุณสามารถรับสิ่งต่อไปนี้:
แล้วลองดูที่รหัสทดสอบ JSON:
แพ็คเกจ com.shun.test; นำเข้า java.io.filewriter; นำเข้า java.io.ioException; นำเข้า java.util.arraylist; นำเข้า java.util.list; นำเข้า com.google.gson.gson; นำเข้า com.shun.student; นำเข้า com.shun.teacher; ระดับสาธารณะ GSONWRITETEST {สาธารณะคงที่ขนาดสุดท้าย int = 100; โมฆะสาธารณะคงที่หลัก (String [] args) พ่น IOException {รายการ <student> stulist = new ArrayList <Tudent> (); สำหรับ (int i = 0; i <size; i ++) {นักเรียน stu = นักเรียนใหม่ (); Stu.setage (25); stu.setid (22); Stu.setName ("Shun"); Stulist.add (Stu); } ครูครู = ครูใหม่ (); ครู Setid (22); อาจารย์. setName ("Shun"); ครู SetStulist (Stulist); String result = new gson (). tojson (ครู); FileWriter fw = ใหม่ fileWriter ("C: // ผู้ใช้ // shun // เดสก์ท็อป // ทดสอบ // json" + ขนาด); fw.write (ผลลัพธ์); fw.close (); }} </span> วิธีการเดียวกันนี้ใช้ในการปรับเปลี่ยนขนาดและทำการทดสอบที่สอดคล้องกัน
จะเห็นได้อย่างชัดเจนว่าขนาดไฟล์ของ JSON และ GPB จะมีความแตกต่างอย่างมากเมื่อปริมาณข้อมูลเพิ่มขึ้นเรื่อย ๆ เห็นได้ชัดว่า JSON มีขนาดใหญ่กว่ามาก
ตารางด้านบนควรชัดเจนขึ้น GPB ของ Big Data นั้นโดดเด่นมาก แต่โดยทั่วไปแล้วไคลเอนต์และเซิร์ฟเวอร์จะไม่โต้ตอบโดยตรงกับข้อมูลขนาดใหญ่ดังกล่าว ข้อมูลขนาดใหญ่ส่วนใหญ่เกิดขึ้นในการส่งเซิร์ฟเวอร์ หากคุณเผชิญกับความต้องการคุณจะต้องส่งไฟล์บันทึกหลายร้อย m ไปยังเซิร์ฟเวอร์อื่นทุกวัน GPB ที่นี่อาจช่วยได้มาก
มีการกล่าวกันว่าเป็นการเปรียบเทียบเชิงลึก แต่การเปรียบเทียบหลักคือขนาดและการเปรียบเทียบเวลาไม่มากเกินไปและไม่มีความแตกต่างกันมาก
สำหรับตัวแยกวิเคราะห์ GSON ที่เลือกในบทความเพื่อนที่สนใจสามารถเลือกแจ็คสันหรือฟาสต์เจสันหรืออื่น ๆ แต่ขนาดไฟล์ที่สร้างขึ้นจะเหมือนกัน แต่เวลาการแยกวิเคราะห์แตกต่างกัน