মরিচা এক্সিকিউটেবল এত বিশাল কেন?


153

সবেমাত্র জাস্টকে খুঁজে পেয়েছেন এবং ডকুমেন্টেশনের প্রথম দুটি অধ্যায় পড়েছেন, আমি ভাষাটি তাদের বিশেষভাবে আকর্ষণীয়ভাবে সংজ্ঞায়িত করার পদ্ধতি এবং উপায়টি পেয়েছি। তাই আমি আমার আঙ্গুলগুলি ভিজা করার সিদ্ধান্ত নিয়েছি এবং হ্যালো ওয়ার্ল্ড দিয়ে শুরু করব ...

আমি উইন্ডোজ 7 x64, বিটিডব্লুতে করেছিলাম।

fn main() {
    println!("Hello, world!");
}

cargo buildফলাফলটি ইস্যু করে এবং অনুসন্ধান করে targets\debugআমি দেখতে পেলাম যে ফলস্বরূপ .exe3 এমবি হচ্ছে। কিছু অনুসন্ধানের পরে (কার্গো কমান্ড লাইন পতাকাগুলির ডকুমেন্টেশনগুলি খুঁজে পাওয়া শক্ত ...) আমি --releaseবিকল্পটি খুঁজে পেয়েছি এবং রিলিজ বিল্ডটি তৈরি করেছি। আমার অবাক করার জন্য, .exe আকারটি 3MB এর পরিবর্তে একটি ক্ষুদ্র পরিমাণে: 2.99MB মাত্র ছোট হয়ে যায়।

সুতরাং, আমি স্বীকার করছি যে আমি মরিচা এবং এর বাস্তুতন্ত্রের জন্য নবাগত, আমার প্রত্যাশাটি ছিল যে কোনও সিস্টেমস প্রোগ্রামিং ভাষা কোনও কমপ্যাক্ট তৈরি করে।

মরিচা কী কী সংকলন করছে সে সম্পর্কে কি কেউ ব্যাখ্যা করতে পারেন, এটি কীভাবে সম্ভব যে এটি একটি 3 টি লাইনার প্রোগ্রাম থেকে এত বিশাল চিত্র তৈরি করে? এটি কি ভার্চুয়াল মেশিনে সংকলন করছে? আমি যে কোনও স্ট্রিপ কমান্ড মিস করেছি (রিলিজ বিল্ডের ভিতরে ডেবাগ তথ্য?)? অন্য কিছুর যা হতে পারে তা বুঝতে সক্ষম হতে পারে?


4
আমি মনে করি 3 এমবিতে কেবলমাত্র হ্যালো ওয়ার্ল্ডই নয়, প্ল্যাটফর্মের জন্য প্রয়োজনীয় সমস্ত পরিবেশ রয়েছে। একই জিনিস Qt সঙ্গে দেখা যেতে পারে। এর অর্থ এই নয় যে আপনি 6-লাইনের প্রোগ্রাম লিখলে আকারটি 6 এমবি হয়ে যাবে। এটি 3Mb এ থাকবে এবং এর পরে খুব ধীরে ধীরে বৃদ্ধি পাবে।
আন্দ্রেই নিকোলেনকো

8
@ আন্ড্রেইন নিকোলেনকো আমি সে সম্পর্কে অবহিত। তবে এটি ইঙ্গিত দেয় যে হয় তারা সি হিসাবে গ্রন্থাগারগুলি পরিচালনা করে না, কেবল একটি চিত্রের জন্য প্রয়োজনীয় যা যুক্ত করা হয় বা অন্য কিছু চলছে something
বিটিক্লার

@ ব্যবহারকারী 2225104 আমার উত্তরটি দেখুন, রুটি সি এর মতো একই (বা অনুরূপ) উপায়ে লাইব্রেরি পরিচালনা করে তবে ডিফল্টরূপে সি আপনার প্রোগ্রামে স্থির লাইব্রেরি সংকলন করে না (কমপক্ষে সি ++ তে)।
এশোফার


1
এটা কি এখন পুরানো? Rustc সংস্করণ 1.35.0 এবং কোনও ক্লিপ বিকল্পের সাথে আমি একটি এক্সাই পাই যা আকারের 137kb। এটি স্বয়ংক্রিয়ভাবে এখন গতিযুক্ত লিখিত সংকলিত হয় বা এর মধ্যে অন্য কিছু ঘটেছিল?
itmuckel

উত্তর:


139

মরিচা এর প্রোগ্রামগুলি সংকলনের জন্য স্ট্যাটিক লিঙ্কিং ব্যবহার করে, এর অর্থ হল যে এমনকি সাধারণ Hello world!প্রোগ্রামের জন্য প্রয়োজনীয় সমস্ত গ্রন্থাগারগুলি আপনার এক্সিকিউটেবলের মধ্যে সংকলিত হবে। এর মধ্যে জং রানটাইমও অন্তর্ভুক্ত।

প্রোগ্রামগুলিকে গতিশীলভাবে লিঙ্ক করতে জাস্টকে বাধ্য করতে, কমান্ড-লাইন আর্গুমেন্ট ব্যবহার করুন -C prefer-dynamic; এর ফলে ফাইল ফাইলের আকার অনেক ছোট হবে তবে রানটাইমের সময়ও আপনার প্রোগ্রামে মরিচা লাইব্রেরিগুলি (এটির রানটাইম সহ) উপলব্ধ থাকতে হবে। এর মূল অর্থ হল আপনার কম্পিউটারটি যদি না থাকে তবে আপনার তাদের সরবরাহ করতে হবে, আপনার মূল স্ট্যাটিক্যালি লিঙ্কযুক্ত প্রোগ্রামের চেয়ে বেশি জায়গা নেওয়া।

বহনযোগ্যতার জন্য আমি আপনাকে স্ট্র্যাটেস্টিকালভাবে মরিচা গ্রন্থাগারগুলি এবং রানটাইমটিকে আপনি যেভাবে করছেন তা যদি আপনি কখনও অন্যদের কাছে বিতরণ করতে চান তবে এটির সাথে সংযুক্ত করার পরামর্শ দেব।


4
@ ব্যবহারকারী 2225104 কার্গো সম্পর্কে নিশ্চিত নয়, তবে গিটহাবের এই বাগ রিপোর্ট অনুসারে , দুর্ভাগ্যক্রমে এটি এখনও সম্ভব হয়নি isn't
এশোফার

2
তবে আপনার সিস্টেমে ২ টিরও বেশি মরিচ এক্সিকিউটেবল হওয়ার সাথে সাথে গতিশীল সংযোগ আপনার স্থান সাশ্রয় করতে শুরু করবে ...
বিনকি

15
আমার মনে হয় না স্থির লিঙ্কিং বিশাল হেলো-ওয়ার্ল্ডকে ব্যাখ্যা করে। এটি কেবল লাইব্রেরির যে অংশগুলিতে ব্যবহার করা হয় কেবল সেখানে লিঙ্ক করা উচিত নয়, এবং হেলো-ওয়ার্ল্ড কার্যত কিছুই ব্যবহার করে না?
ম্যাক্সবি

8
বিটিক্লিকারcargo rustc [--debug or --release] -- -C prefer-dynamic
জ্যাচ

3
@ ডাবরোস আপনাকে অনেক ধন্যবাদ আমি এই সম্পর্কিত আরএফসি ট্র্যাক করে চলেছি । জাস্ট সিস্টেম প্রোগ্রামিংকে টার্গেট করে এটি সত্যিই মাতাল।
ফ্রাঙ্কলিন ইউ

62

আমার কাছে চেষ্টা করার মতো কোনও উইন্ডোজ সিস্টেম নেই, তবে লিনাক্সে, একটি স্ট্যাটিক্যালি সংকলিত মরিচা হ্যালো ওয়ার্ল্ডটি আসলে সমতুল্য সি এর চেয়ে ছোট If আপনি যদি আকারে একটি বিশাল পার্থক্য দেখছেন, সম্ভবত এটি আপনি মরচে এক্সিকিউটেবলকে সংযুক্ত করছেন কারণ স্থিতিশীল এবং গ গতিশীলভাবে এক।

ডায়নামিক লিঙ্কিংয়ের সাথে, আপনাকে কেবল কার্যকর করার জন্য নয়, সমস্ত গতিশীল গ্রন্থাগারগুলির আকারও বিবেচনায় নেওয়া উচিত।

সুতরাং, আপনি যদি আপেলকে আপেলের সাথে তুলনা করতে চান তবে আপনাকে অবশ্যই নিশ্চিত করতে হবে যে উভয়ই গতিশীল বা উভয়ই স্থিতিশীল। বিভিন্ন সংকলকের আলাদা আলাদা ডিফল্ট থাকবে, সুতরাং একই ফলাফলটি তৈরি করতে আপনি কেবল সংকলক ডিফল্টের উপর নির্ভর করতে পারবেন না।

আপনি যদি আগ্রহী হন তবে আমার ফলাফলগুলি এখানে:

-আরড-আর - r-- 1 এআইজ এআইআই 63 এপ্রিল 5 14:26 printf.c
-rwxr-xr-x 1 এআইজ 6696 এপ্রিল 5 14:27 printf.dyn
-rwxr-xr-x 1 এআইজ 829344 এপ্রিল 5 14:27 printf.static
-আরড-আর - r-- 1 এআইজ এআইআই 59 এপ্রিল 5 14:26 puts.c
-rwxr-xr-x 1 এআইজ এআইআই 6696 এপ্রিল 5 14:27 puts.dyn
-rwxr-xr-x 1 এআইজ 829344 এপ্রিল 5 14:27 puts.static
-rwxr-xr-x 1 এআইজ এআইএন 8712 এপ্রিল 5 14:28 rust.dyn
-আরড-আর - r-- 1 এআইজ এআইআই 46 এপ্রিল 5 14:09 rust.rs
-rwxr-xr-x 1 এআইজ এআইআই 661496 এপ্রিল 5 14:28 rust.static

এই জিসিসি (ডেবিয়ান 4.9.2-10) 4.9.2 সঙ্গে কম্পাইল এবং rustc 1.0.0-রাত্রিকালীন (d17d6e7f1 2015-04-02) (বিল্ট 2015-04-03), ডিফল্ট অপশন সঙ্গে উভয় সঙ্গে ছিল -staticজিসিসি এবং -C prefer-dynamicজন্য rustc।

আমার কাছে সি হ্যালো ওয়ার্ল্ডের দুটি সংস্করণ ছিল কারণ আমি ভেবেছিলাম puts()কম সংকলন ইউনিটের সাহায্যে লিঙ্ক ব্যবহার করতে পারি ।

যদি আপনি এটি উইন্ডোজে পুনরুত্পাদন করার চেষ্টা করতে চান তবে আমি যে উত্সগুলি ব্যবহার করেছি তা এখানে:

printf.c:

#include <stdio.h>
int main() {
  printf("Hello, world!\n");
}

puts.c:

#include <stdio.h>
int main() {
  puts("Hello, world!");
}

rust.rs

fn main() {
    println!("Hello, world!");
}

এছাড়াও, মনে রাখবেন যে বিভিন্ন পরিমাণে ডিবাগিং তথ্য বা বিভিন্ন অপ্টিমাইজেশনের স্তরগুলিও একটি পার্থক্য আনতে পারে। তবে আমি প্রত্যাশা করি যদি আপনি একটি বিশাল পার্থক্য দেখেন তবে এটি স্থির বনাম গতিশীল সংযোগের কারণে।


27
জিসিসি হ'ল প্রিন্টএফ করার জন্য যথেষ্ট স্মার্ট -> প্রতিস্থাপন নিজেই রাখে, এজন্য ফলাফলগুলি অভিন্ন।
bluss

6
2018 এর মতো আপনি যদি একটি নির্মাতাকে তুলনা করতে চান তবে এক্সিকিউটেবলগুলিকে "ফালা" ফেলার কথা মনে রাখবেন, হ্যালো ওয়ার্ল্ড হিসাবে আমার সিস্টেমে রস্ট এক্সিকিউটেবল হ'ল পুরো 5.3MB তবে আপনি যখন সমস্ত ডিবাগ প্রতীকগুলি সরিয়ে ফেলেন তখন এর 10% এরও নিচে নেমে যায় এবং যেমন।
ম্যাটি ভির্ককুনেন

@ মাট্টিভির্ককুনেন: এখনও ২০২০ সালের ঘটনা; প্রাকৃতিক আকারটি ছোট মনে হয় (5.3M এর কাছাকাছি কোথাও নেই) তবে কোডের সাথে প্রতীকগুলির অনুপাত এখনও বেশ চরম। ডিবাগ বিল্ড, সেন্টোস 7-তে মরিচা 1.34.0 এ খাঁটি ডিফল্ট বিকল্পগুলি সহ strip -s1.6M থেকে 190K এ নেমে আসে। রিলিজ বিল্ড (ডিফল্ট প্লাস opt-level='s', lto = trueএবং panic = 'abort'আকার ছোট করার জন্য) 623K থেকে 158K এ নেমে যায়।
শ্যাডোর্যাঞ্জার

স্থির এবং গতিশীল আপেল কীভাবে পার্থক্য করবেন? দ্বিতীয়টি স্বাস্থ্যকর শোনাচ্ছে না।
এলএফ

30

কার্গো দিয়ে সংকলন করার সময়, আপনি গতিশীল লিঙ্ক ব্যবহার করতে পারেন:

cargo rustc --release -- -C prefer-dynamic

এটি বাইনারিটির আকার নাটকীয়ভাবে হ্রাস করবে, কারণ এটি এখন গতিশীলভাবে সংযুক্ত।

লিনাক্স-এ, কমপক্ষে, আপনি stripকমান্ডটি ব্যবহার করে চিহ্নগুলির বাইনারিগুলিও ছিনিয়ে নিতে পারেন:

strip target/release/<binary>

এটি বেশিরভাগ বাইনারিগুলির আকার প্রায় অর্ধেক করে দেবে।


8
কিছু কিছু পরিসংখ্যান, হ্যালো ওয়ার্ল্ডের ডিফল্ট প্রকাশ সংস্করণ (লিনাক্স x86_64)। অগ্রাধিকার-গতিশীল 8904 বি সহ 3.5 এম, 6392 বি কে ছিনিয়ে নিয়েছে
জিতরেক্স

30

মরিচা বাইনারি আকার কমাতে সমস্ত উপায়ের একটি সংক্ষিপ্তসার জন্য, min-sized-rustসংগ্রহস্থলটি দেখুন।

বাইনারি আকার কমাতে বর্তমান উচ্চ স্তরের পদক্ষেপগুলি হ'ল:

  1. মরিচা 1.32.0 বা আরও নতুন ব্যবহার করুন (যা jemallocডিফল্টরূপে অন্তর্ভুক্ত নয় )
  2. নিম্নলিখিতটি যুক্ত করুন Cargo.toml
[profile.release]
opt-level = 'z'     # Optimize for size.
lto = true          # Enable Link Time Optimization
codegen-units = 1   # Reduce number of codegen units to increase optimizations.
panic = 'abort'     # Abort on panic
  1. ব্যবহার করে রিলিজ মোডে তৈরি করুন cargo build --release
  2. stripফলাফল বাইনারি চালান ।

nightlyমরিচা ব্যবহার করে আরও অনেক কিছু করা যায় , তবে min-sized-rustঅস্থির বৈশিষ্ট্যগুলি ব্যবহারের কারণে সময়ের সাথে সাথে এটি পরিবর্তন হওয়ার সাথে সাথে আমি সেই তথ্যটি রেখে দেব ।

আপনি #![no_std]মরিচা অপসারণ করতেও ব্যবহার করতে পারেন libstd। দেখুন min-sized-rustবিস্তারিত জানার জন্য।


-10

এটি একটি বৈশিষ্ট্য, না একটি বাগ সংশোধন করা হয়!

আপনি প্রোগ্রামে ব্যবহৃত লাইব্রেরি সংস্করণগুলি ( প্রকল্পের সাথে সম্পর্কিত কার্গো.টমল ফাইলটিতে ) নির্দিষ্ট করতে পারেন (এমনকি অন্তর্ভুক্তগুলিও) লাইব্রেরির সংস্করণের সামঞ্জস্যতা নিশ্চিত করতে। অন্যদিকে এটির জন্য প্রয়োজনীয় নির্দিষ্ট গ্রন্থাগারটি কার্যকরভাবে কার্যকর হওয়ার সাথে স্ট্যাটিকভাবে লিঙ্কযুক্ত থাকা এবং বড় রান-টাইম চিত্র তৈরি করা দরকার।

আরে, এটি আর 1978 নয় - অনেকের কম্পিউটারে 2 এমবি র‌্যামের বেশি থাকে :-)


9
গ্রন্থাগারের সংস্করণগুলি নির্দিষ্ট করুন [...] এর জন্য নির্দিষ্ট গ্রন্থাগারটি স্থিতিশীলভাবে সংযুক্ত করা দরকার - না, এটি নয়। প্রচুর কোড উপস্থিত রয়েছে যেখানে গ্রন্থাগারগুলির যথাযথ সংস্করণগুলি গতিশীলভাবে সংযুক্ত রয়েছে।
শেপমাস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.