ความแตกต่างระหว่างห้องสมุดแบบคงที่และที่ใช้ร่วมกัน?


560

อะไรคือความแตกต่างระหว่างห้องสมุดแบบคงที่และที่ใช้ร่วมกัน?

ฉันใช้ Eclipse และมีโปรเจ็กต์หลายประเภทรวมถึง Static Libraries และ Shared Libraries? คนหนึ่งได้เปรียบกว่าอีกคนหนึ่งหรือเปล่า?


4
Wikipedia มีคำอธิบายที่ดีเกี่ยวกับความแตกต่างระหว่างไลบรารีแบบคงที่ไดนามิกและแบบแบ่งใช้
Adam Holmberg

คำตอบ:


745

ไลบรารีที่แบ่งใช้คือ. so (หรือใน Windows .dll หรือไฟล์ OS X .dylib) รหัสทั้งหมดที่เกี่ยวข้องกับไลบรารีอยู่ในไฟล์นี้และมันถูกอ้างอิงโดยโปรแกรมที่ใช้มันในเวลาทำงาน โปรแกรมที่ใช้ไลบรารีที่แบ่งใช้จะอ้างอิงถึงรหัสที่ใช้ในไลบรารีที่ใช้ร่วมกันเท่านั้น

ไลบรารีแบบสแตติกคือไฟล์. a (หรือใน Windows .lib) รหัสทั้งหมดที่เกี่ยวข้องกับห้องสมุดอยู่ในไฟล์นี้และมันเชื่อมโยงโดยตรงกับโปรแกรมในเวลารวบรวม โปรแกรมที่ใช้ไลบรารีแบบคงที่จะคัดลอกรหัสที่ใช้จากห้องสมุดแบบคงที่และทำให้เป็นส่วนหนึ่งของโปรแกรม [Windows ยังมีไฟล์. lib ที่ใช้ในการอ้างอิงไฟล์. dll แต่จะทำในลักษณะเดียวกับไฟล์แรก]

มีข้อดีและข้อเสียในแต่ละวิธี:

  • ไลบรารีที่แบ่งใช้ลดจำนวนรหัสที่ซ้ำกันในแต่ละโปรแกรมที่ใช้ประโยชน์จากไลบรารีทำให้ไบนารีมีขนาดเล็ก นอกจากนี้ยังช่วยให้คุณสามารถแทนที่วัตถุที่ใช้ร่วมกันด้วยวัตถุที่เทียบเท่ากับการใช้งานได้ แต่อาจเพิ่มประโยชน์ด้านประสิทธิภาพโดยไม่จำเป็นต้องคอมไพล์โปรแกรมที่ใช้งานใหม่ ไลบรารีที่แบ่งใช้จะมีค่าใช้จ่ายเพิ่มเติมเล็กน้อยสำหรับการดำเนินการของฟังก์ชั่นรวมถึงค่าใช้จ่ายในการโหลดขณะทำงานเนื่องจากสัญลักษณ์ทั้งหมดในไลบรารีจะต้องเชื่อมต่อกับสิ่งที่พวกเขาใช้ นอกจากนี้ไลบรารีที่แบ่งใช้สามารถโหลดลงในแอ็พพลิเคชันในขณะใช้งานซึ่งเป็นกลไกทั่วไปสำหรับการนำระบบปลั๊กอินไบนารี

  • ไลบรารีแบบสแตติกเพิ่มขนาดโดยรวมของไบนารี แต่หมายความว่าคุณไม่จำเป็นต้องพกสำเนาของไลบรารีที่ใช้อยู่ เนื่องจากรหัสเชื่อมต่อในเวลารวบรวมจึงไม่มีค่าใช้จ่ายในการโหลดขณะทำการเพิ่มเติม รหัสนั้นอยู่ตรงนั้น

โดยส่วนตัวแล้วฉันชอบไลบรารีที่ใช้ร่วมกัน แต่ใช้สแตติกไลบรารีเมื่อต้องการให้แน่ใจว่าไบนารีนั้นไม่มีการอ้างอิงภายนอกจำนวนมากที่อาจพบได้ยากเช่นเวอร์ชันเฉพาะของไลบรารีมาตรฐาน C ++ หรือไลบรารี Boost C ++ รุ่นเฉพาะ


2
"แทนที่วัตถุที่ใช้ร่วมกันด้วย ... เทียบเท่ากับหน้าที่ แต่อาจ [ปรับปรุง] ประสิทธิภาพ": โดยเฉพาะฟังก์ชั่นที่ต้องเผชิญกับผู้โทรในการใช้ความหมายของ API (อินเตอร์เฟสการเขียนโปรแกรมประยุกต์: ลายเซ็นของฟังก์ชันและตัวแปรรวมถึงชนิด) ฟังก์ชั่นอาจแตกต่างกันในมากกว่า perf .: เช่นฟังก์ชั่นมักจะบันทึกไฟล์ -> ยังเข้าสู่เซิร์ฟเวอร์ TCP: พอร์ตที่คาดไว้ใน $ MY_APP_LOG_SERVER
Tony Delroy

1
"[.sos inca a] ค่าใช้จ่ายเพิ่มเติมเล็กน้อยสำหรับการดำเนินการของฟังก์ชั่น" - เป็นไปได้ (ถ้ากลุ่มฟังก์ชั่น / การสั่งซื้อได้รับการปรับให้เหมาะสมที่สุดสำหรับตำแหน่งแคชในลิงก์คงที่หรือเนื่องจากแปลกประหลาดใน OS / ตัวโหลด / คอมไพเลอร์ / สถาปัตยกรรมเช่น cross -segment / large-pointer perf. การลงโทษ) แต่ในสถาปัตยกรรม / คอมไพเลอร์จำนวนมากการตั้งค่าตัวเชื่อมโยงแบบไดนามิกแพทช์การโทรเพื่อสร้าง opcodes เครื่องโทรศัพท์ที่แน่นอนเดียวกัน
Tony Delroy

2
"ขณะที่โค้ดเชื่อมต่อในเวลาคอมไพล์ไม่มีค่าใช้จ่ายในการโหลดเพิ่มเติมใด ๆ รหัสนั้นอยู่ที่นั่น" - ใช่และไม่ใช่ ... ทุกอย่างอยู่ในอิมเมจที่เรียกใช้งานได้ซึ่งพร้อมที่จะทำเพจเอาต์หากต้องการการดำเนินการ แต่ - เริ่มจากสถานการณ์ที่โปรแกรมของคุณไม่ได้ทำงานเมื่อเร็ว ๆ นี้เพียงพอที่จะแคช - ด้วยไลบรารีที่ใช้ร่วมกัน หรือบางอย่าง) ว่าระบบปฏิบัติการไดรเวอร์หรือโปรแกรมที่กำลังรันอื่นจะโหลดไลบรารีที่แชร์ที่แอพของคุณต้องการใช้แล้วซึ่งอาจเป็นในแคชและโปรแกรมของคุณเริ่มต้นและทำงานได้เร็วขึ้น
Tony Delroy

15
สิ่งที่บางคนล้มเหลวในการพูดถึงก็คือเมื่อมีไลบรารีแบบคงที่คอมไพเลอร์รู้ว่าฟังก์ชันใดที่แอปพลิเคชันของคุณต้องการและสามารถปรับให้เหมาะสมโดยรวมเฉพาะฟังก์ชั่นเหล่านั้น สิ่งนี้สามารถลดขนาดห้องสมุดลงได้อย่างมากโดยเฉพาะถ้าคุณใช้ชุดย่อยขนาดเล็กของห้องสมุดที่มีขนาดใหญ่จริงๆ!
jduncanator

1
คำตอบนี้สามารถจัดระเบียบได้ดีขึ้น การสร้างรายการสัญลักษณ์แสดงหัวข้อย่อยสำหรับข้อดี / ข้อเสียหรือตารางแสดงความแตกต่างในแต่ละมิติที่มีความแตกต่าง
ElefEnt

377

ห้องสมุดคงเป็นเหมือนร้านหนังสือและห้องสมุดสาธารณะเป็นเหมือน ... ห้องสมุด เมื่อก่อนคุณจะได้รับสำเนาของหนังสือ / ฟังก์ชันเพื่อนำกลับบ้าน เมื่อคุณและคนอื่น ๆ ไปที่ห้องสมุดเพื่อใช้หนังสือ / ฟังก์ชั่นเดียวกัน ดังนั้นใครก็ตามที่ต้องการใช้ห้องสมุด (แบ่งปัน) จำเป็นต้องรู้ว่าอยู่ที่ไหนเพราะคุณต้อง "ไปรับ" หนังสือ / ฟังก์ชั่น ด้วยห้องสมุดคงหนังสือ / ฟังก์ชั่นเป็นของคุณเองและคุณเก็บไว้ในบ้าน / โปรแกรมของคุณและเมื่อคุณมีมันคุณไม่สนใจที่ไหนหรือเมื่อคุณได้รับมัน


70

ย่อ:

  • การเชื่อมโยงแบบคงที่: หนึ่งปฏิบัติการขนาดใหญ่
  • การลิงก์แบบไดนามิก: ไฟล์ปฏิบัติการขนาดเล็กพร้อมไฟล์ไลบรารีหนึ่งไฟล์ขึ้นไป (ไฟล์. dll บน Windows, .so บน Linux หรือ. dylib บน macOS)

1
คำตอบนี้ดีที่สุดสำหรับฉันเพราะมันใช้งานได้จริง มันสมเหตุสมผลมากกว่าคำอุปมาที่ไม่ได้พูดถึงสิ่งที่เกิดขึ้นจริงในคอมพิวเตอร์ หลังจากรู้ว่านี่คือสิ่งที่เกิดขึ้นฉันก็หยั่งรู้ถึงความหมายอื่นทั้งหมด
off99555

36

สำหรับไลบรารีแบบสแตติกรหัสจะถูกแยกออกจากไลบรารีโดยตัวเชื่อมโยงและใช้เพื่อสร้างปฏิบัติการขั้นสุดท้าย ณ จุดที่คุณรวบรวม / สร้างแอปพลิเคชันของคุณ ปฏิบัติการขั้นสุดท้ายนั้นไม่มีการพึ่งพาไลบรารีในขณะดำเนินการ

สำหรับไลบรารีที่ใช้ร่วมกันคอมไพเลอร์ / ลิงเกอร์จะตรวจสอบว่าชื่อที่คุณเชื่อมโยงนั้นมีอยู่ในไลบรารีเมื่อมีการสร้างแอปพลิเคชัน แต่ไม่ย้ายรหัสไปยังแอปพลิเคชัน ณ รันไทม์ไลบรารีที่แบ่งใช้ต้องพร้อมใช้งาน

ภาษาการเขียนโปรแกรม C นั้นไม่มีแนวคิดของไลบรารีแบบคงที่หรือแบบแบ่งใช้ซึ่งเป็นคุณลักษณะการปรับใช้อย่างสมบูรณ์

โดยส่วนตัวแล้วฉันชอบที่จะใช้ห้องสมุดแบบสแตติกเพราะทำให้การกระจายซอฟต์แวร์ง่ายขึ้น อย่างไรก็ตามนี่เป็นความเห็นที่ในอดีตมีการหลั่งโลหิตออกมาเป็นรูปเป็นร่าง


5
+1 สำหรับ "ภาษาการเขียนโปรแกรม C นั้นไม่มีแนวคิดของไลบรารีแบบคงที่หรือแบบแบ่งใช้ - มันเป็นคุณสมบัติการใช้งานอย่างสมบูรณ์"
Tiger

1
สวัสดี anon / @Tiger ทำไมคุณกล่าวว่า "ภาษาการเขียนโปรแกรม C เองไม่มีแนวคิดของไลบรารีแบบคงที่หรือที่ใช้ร่วมกัน คุณช่วยอธิบายรายละเอียดเล็กน้อยหรือชี้ให้ฉันอ้างอิงที่เหมาะสมได้ไหม
Sunil Shahu

@SunilShahu วิธีการรวบรวมและเชื่อมโยงโปรแกรมเฉพาะกับคอมไพเลอร์และลิงเกอร์ที่คุณใช้คือการใช้งานเฉพาะของภาษา โดยทั่วไปแล้วความหมายของภาษาไม่ได้อธิบายว่าภาษาควรนำไปปฏิบัติหรือสร้างขึ้นได้อย่างไรมีเพียงฟังก์ชันการทำงานไวยากรณ์ไวยากรณ์ ฯลฯ
JC Rocamonde

@SunilShahu ตัวอย่างที่ชัดเจนมากขึ้นอาจเป็น JavaScript เช่นที่สเปค (EcmaScript) อธิบายคุณสมบัติของภาษา แต่มันเป็นผู้ขายที่แตกต่างกันที่จัดส่งล่าม JS (เครื่องมือเบราว์เซอร์หรือ Node.js เป็นต้น) ในอีกทางหนึ่งภาษา Python Programming Language มีการนำไปใช้งานหลายอย่าง อย่างเป็นทางการคือ CPython แต่มีคนอื่นเขียนเป็นภาษาอื่น
JC Rocamonde

31

ไลบรารีแบบสแตติกถูกรวบรวมเป็นส่วนหนึ่งของแอปพลิเคชันในขณะที่ไลบรารีแบบแบ่งใช้ไม่ใช่ เมื่อคุณเผยแพร่แอปพลิเคชั่นที่ขึ้นอยู่กับ libaries ที่แชร์ไลบรารีเช่น dll ของบน MS Windows จะต้องมีการติดตั้ง

ข้อดีของไลบรารีแบบสแตติกคือไม่มีการอ้างอิงที่จำเป็นสำหรับผู้ใช้ที่เรียกใช้แอปพลิเคชัน - เช่นพวกเขาไม่จำเป็นต้องอัปเกรด DLL ของพวกเขา ข้อเสียคือแอปพลิเคชันของคุณมีขนาดใหญ่กว่าเนื่องจากคุณจัดส่งไปพร้อมกับไลบรารีทั้งหมดที่ต้องการ

เช่นเดียวกับการนำไปสู่แอปพลิเคชั่นขนาดเล็กไลบรารีที่ใช้ร่วมกันจะช่วยให้ผู้ใช้สามารถใช้ไลบรารีของตัวเองซึ่งอาจเป็นเวอร์ชั่นที่ดีกว่าแทนที่จะใช้แอพพลิเคชั่นที่เป็นส่วนหนึ่งของแอพพลิเคชั่น


3
DLL นรกในขณะที่มันเป็นที่รู้จัก
gheese

1
"ไลบรารีสแตติกถูกรวบรวมเป็นส่วนหนึ่งของแอปพลิเคชัน" ... สแตติกไลบรารีจะถูกรวบรวมเป็นสแตติกไลบรารีและเชื่อมโยงเป็นส่วนหนึ่งของแอปพลิเคชัน
idclev 463035818

19

ข้อได้เปรียบที่สำคัญที่สุดของไลบรารีที่ใช้ร่วมกันคือมีโค้ดที่โหลดในหน่วยความจำเพียงชุดเดียวไม่ว่าจะใช้กระบวนการกี่ไลบรารี สำหรับไลบรารีแบบสแตติกแต่ละกระบวนการจะได้รับสำเนาของตัวเอง สิ่งนี้สามารถนำไปสู่การสูญเสียความทรงจำที่สำคัญ

OTOH ข้อดีของห้องสมุดแบบคงที่คือทุกสิ่งรวมอยู่ในแอปพลิเคชันของคุณ ดังนั้นคุณไม่ต้องกังวลว่าลูกค้าจะมีไลบรารี่ที่ถูกต้อง (และเวอร์ชั่น) ในระบบของพวกเขา


1
อิมเมจที่รันได้นั้นใหญ่กว่าบนดิสก์รวมถึงในหน่วยความจำเมื่อใช้ libs แบบสแตติก
JustJeff

ถูกต้องนั่นคือสิ่งที่ฉันพูดถึงเมื่อฉันบอกว่าทุกอย่างรวมอยู่ในใบสมัครของคุณ
Jasmeet

นอกจากนี้.soไฟล์บนระบบ * nix คือไลบรารีที่แชร์ (ไดนามิก) ของ kinda
snr

6

นอกเหนือจากคำตอบอื่น ๆ แล้วสิ่งหนึ่งที่ยังไม่ได้กล่าวถึงคือการแยกส่วน:

ให้ฉันพูดเกี่ยวกับรหัสการผลิตในโลกแห่งความเป็นจริงที่ฉันได้รับ:

ซอฟต์แวร์ที่มีขนาดใหญ่มากซึ่งสร้างจากโครงการ 300 โครงการ (ด้วย visual studio) ซึ่งส่วนใหญ่สร้างเป็น lib แบบคงที่และในที่สุดลิงก์ทั้งหมดเข้าด้วยกันในไฟล์ปฏิบัติการขนาดใหญ่คุณจะพบกับปัญหาต่อไปนี้:

เวลาเชื่อมโยงนั้นยาวมาก คุณอาจจบลงด้วยการเชื่อมโยงมากกว่า 15 นาทีสำหรับสมมติว่า 10s ของเวลาในการรวบรวม - เครื่องมือบางอย่างอยู่บนหัวของพวกเขาด้วยการปฏิบัติการที่ยิ่งใหญ่เช่นเครื่องมือตรวจสอบหน่วยความจำที่ต้องใช้รหัส คุณอาจถึงขีด จำกัด ที่ถูกมองว่าเป็นคนโง่

ปัญหาที่มากขึ้นคือการแยกซอฟต์แวร์ของคุณออกจากตัวอย่างในโลกแห่งความเป็นจริงไฟล์ส่วนหัวของทุกโครงการสามารถเข้าถึงได้จากโครงการอื่น ๆ ผลที่ตามมามันง่ายมากสำหรับผู้พัฒนารายเดียวที่จะเพิ่มการพึ่งพา มันเป็นเพียงเกี่ยวกับการรวมส่วนหัวเพราะการเชื่อมโยงในตอนท้ายจะช่วยให้ค้นหาสัญลักษณ์ มันจบลงด้วยการพึ่งพาการขี่จักรยานที่น่ากลัวและความยุ่งเหยิงอย่างสมบูรณ์

ด้วยไลบรารีที่แบ่งใช้มันเป็นงานพิเศษเพราะนักพัฒนาจะต้องแก้ไขระบบการสร้างโครงการเพื่อเพิ่มไลบรารีที่ต้องพึ่งพา ฉันสังเกตเห็นว่ารหัสห้องสมุดที่ใช้ร่วมกันมีแนวโน้มที่จะเสนอรหัส API ที่สะอาดกว่า


2
-------------------------------------------------------------------------
|  +-  |    Shared(dynamic)       |   Static Library (Linkages)         |
-------------------------------------------------------------------------
|Pros: | less memory use          |   an executable, using own libraries|
|      |                          |     ,coming with the program,       |
|      |                          |   doesn't need to worry about its   |
|      |                          |   compilebility subject to libraries|
-------------------------------------------------------------------------
|Cons: | implementations of       |   bigger memory uses                |
|      | libraries may be altered |                                     |
|      | subject to OS  and its   |                                     |
|      | version, which may affect|                                     |
|      | the compilebility and    |                                     |
|      | runnability of the code  |                                     |
-------------------------------------------------------------------------
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.