জাভাতে System.arraycopy নেটিভ কেন?


85

আমি জাভা উত্সে অবাক হয়ে দেখেছি যে সিস্টেম.আররেইকপি একটি স্থানীয় পদ্ধতি।

অবশ্যই কারণটি কারণ এটি দ্রুত। কিন্তু কোডটি কোন স্থানীয় কৌশল ব্যবহার করে যা এটি দ্রুততর করে তোলে?

কেন কেবল মূল অ্যারেটি লুপ করে প্রতিটি পয়েন্টারটিকে নতুন অ্যারেতে অনুলিপি করবেন না - নিশ্চয় এটি এত ধীর এবং জটিল নয়?

উত্তর:


83

নেটিভ কোড, এটা একটা একক সঙ্গে কাজ করা যেতে পারে memcpy/ memmove, যেমন উল্টোদিকে এন স্বতন্ত্র কপি অপারেশন। পারফরম্যান্সের পার্থক্য যথেষ্ট।


8
আসলে, কেবলমাত্র কয়েকটি সাব-কেসগুলি / arraycopyব্যবহার করে প্রয়োগ করা যেতে পারে । অন্যদের অনুলিপি করা প্রতিটি উপাদানগুলির জন্য একটি রানটাইম ধরণের চেক প্রয়োজন। memcpymemmove
স্টিফেন সি

4
@ স্টেফেন সি, আকর্ষণীয় - কেন এটি?
প্যাটার তারেক

4
@ পিটার টার্ক - বস্তুর Object[]সাথে জনবহুল থেকে কপি করার বিষয়টি বিবেচনা করুন । Java.sun.com/javase/6/docs/api/java/lang/… এর শেষ অনুচ্ছেদটি দেখুনStringString[]
স্টিফেন সি

4
পিটার, অবজেক্ট [] এবং বাইট [] + চর [] হ'ল প্রায়শই অনুলিপি করা হয়, তাদের কোনওটিরই সুস্পষ্ট ধরণের চেকের প্রয়োজন নেই। সংকলক পর্যাপ্ত পরিমাণে 99.9% ক্ষেত্রে প্রয়োজন না হলে এটি পরীক্ষা না করে পর্যাপ্ত স্মার্ট। মজার অংশটি হ'ল ছোট আকারের অনুলিপি (ক্যাশে লাইনের চেয়ে কম) বেশ প্রভাবশালী, তাই ছোট আকারের স্টাফগুলি দ্রুত হওয়ার জন্য "মেমকি" সত্যিই গুরুত্বপূর্ণ।
বেটসেস

4
@ জেইনিলওয়াছনী উভয়ই memcpymemmoveও (এন), তবে ফিম সিমড অপটিমাইজেশনগুলি few timesদ্রুততর হয়, তাই আপনি বলতে পারেন তারা ও (এন / এক্স), যেখানে এক্স এই ফাংশনগুলিতে ব্যবহৃত অপ্টিমাইজেশনের উপর নির্ভরশীল
ufoq

16

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

এবং এটি একটি একক দিয়ে লেখা যায় নাmemcpy() , কারণ ওভারল্যাপিং অ্যারেগুলির দ্বারা প্রয়োজনীয় শব্দার্থতত্ত্বগুলির কারণে।


4
ভাল, তাই memmove। যদিও আমি মনে করি না যে এটি এই প্রশ্নের প্রসঙ্গে অনেক বেশি পার্থক্য করে makes
পিয়েটার তারেক

মেমমোভ () নয়, অন্য উত্তরে @ স্টিফেন সি-র মন্তব্য দেখুন।
ব্যবহারকারী 207421

ইতিমধ্যে দেখেছি যেহেতু এটি আমার নিজের উত্তর হতে হয়েছিল ;-) তবে যাইহোক ধন্যবাদ।
প্যাটার টারিক

4
@ গীক অ্যারেগুলি ওভারল্যাপ করে। যদি উত্স এবং লক্ষ্য অ্যারে এবং একই এবং কেবল অফসেটগুলি পৃথক হয় তবে আচরণটি সাবধানতার সাথে নির্দিষ্ট করা হয়েছে এবং মেমকি () মেনে চলে না।
ব্যবহারকারী 207421

4
এটা তোলে করতে পারবে না জাভা লেখা যেতে? অবজেক্টের সাবক্লাসগুলি হ্যান্ডেল করার জন্য একটির জেনেরিক পদ্ধতি এবং তারপরে আদিম ধরণের প্রত্যেকটির জন্য একটি করে লেখা যায় না?
মাইকেল ডারস্ট

11

এটি অবশ্যই বাস্তবায়ন নির্ভর।

হটস্পট এটিকে "অভ্যন্তরীণ" হিসাবে বিবেচনা করবে এবং কল সাইটে কোড সন্নিবেশ করবে। এটি মেশিন কোড, পুরানো সি কোডটি ধীর নয়। এর অর্থ হ'ল পদ্ধতির স্বাক্ষর নিয়ে সমস্যাগুলি অনেকাংশে দূরে চলে যায়।

একটি সাধারণ অনুলিপি লুপ যথেষ্ট সহজ যে সুস্পষ্ট অপ্টিমেশন এটি প্রয়োগ করা যেতে পারে। উদাহরণস্বরূপ লুপ আনরোলিং। ঠিক কী ঘটে তা আবার বাস্তবায়ন নির্ভর।


4
এটি একটি খুব শালীন উত্তর :), এসপিএস। অন্তর্নিহিত উল্লেখ। ডাব্লু / ও সেগুলি সাধারণ পুনরাবৃত্তিটি দ্রুততর হতে পারে কারণ এটি সাধারণত জেআইটি কর্তৃক
অনিবন্ধিত রয়েছে

4

আমার নিজের পরীক্ষায় System.arraycopy () একাধিক মাত্রার অ্যারে অনুলিপি করার জন্য লুপের জন্য ইন্টারলিভিংয়ের চেয়ে 10 থেকে 20 গুণ বেশি গতিযুক্ত:

float[][] foo = mLoadMillionsOfPoints(); // result is a float[1200000][9]
float[][] fooCpy = new float[foo.length][foo[0].length];
long lTime = System.currentTimeMillis();
System.arraycopy(foo, 0, fooCpy, 0, foo.length);
System.out.println("native duration: " + (System.currentTimeMillis() - lTime) + " ms");
lTime = System.currentTimeMillis();

for (int i = 0; i < foo.length; i++)
{
    for (int j = 0; j < foo[0].length; j++)
    {
        fooCpy[i][j] = foo[i][j];
    }
}
System.out.println("System.arraycopy() duration: " + (System.currentTimeMillis() - lTime) + " ms");
for (int i = 0; i < foo.length; i++)
{
    for (int j = 0; j < foo[0].length; j++)
    {
        if (fooCpy[i][j] != foo[i][j])
        {
            System.err.println("ERROR at " + i + ", " + j);
        }
    }
}

এই মুদ্রণ:

System.arraycopy() duration: 1 ms
loop duration: 16 ms

10
যদিও এই প্রশ্নটি পুরানো, কেবলমাত্র রেকর্ডের জন্য: এটি ন্যায্য মানদণ্ড নয় (এই জাতীয় মানদণ্ড যদি প্রথম স্থানে বোঝায় তবে প্রশ্নটি ছেড়ে দিন)। System.arraycopyঅগভীর অনুলিপি করে (কেবলমাত্র অভ্যন্তরীণগুলির উল্লেখগুলিfloat[] অনুলিপি করা হয়), তবে আপনার নেস্টেড- forলুপগুলি একটি গভীর অনুলিপি ( floatদ্বারা float) সম্পাদন করে । এর পরিবর্তনটি ব্যবহারে fooCpy[i][j]প্রতিফলিত হবে তবে নেস্টেড- লুপগুলি ব্যবহার করা হবে না । fooSystem.arraycopyfor
মিসবারনার

4

এখানে কিছু কারন আছে:

  1. জেআইটি ম্যানুয়ালি লিখিত সি কোড হিসাবে দক্ষ নিম্ন স্তরের কোড তৈরি করার সম্ভাবনা কম। নিম্ন স্তরের সি ব্যবহার করে প্রচুর অপটিমাইজেশন সক্ষম করা যায় যা জেনেরিক জেআইটি সংকলকটির পক্ষে করা অসম্ভবের কাছাকাছি।

    কিছু কৌশল এবং হাতের লেখা সি বাস্তবায়নের গতি তুলনা জন্য এই লিঙ্কে দেখুন (আমার মনে, কিন্তু নীতি একই): চেক করুন এই নিখুঁত আমার মনে গতি উন্নত

  2. সি সংস্করণ অ্যারে সদস্যদের ধরন এবং আকারের থেকে অনেকটা স্বতন্ত্র। জাভাতে এটি করা সম্ভব নয় কারণ মেমরির কাঁচা ব্লক (উদাহরণস্বরূপ পয়েন্টার) হিসাবে অ্যারের সামগ্রীগুলি পাওয়ার কোনও উপায় নেই।


4
জাভা কোডটি অনুকূলিত হতে পারে get আসলে যা ঘটে তা হ'ল মেশিন কোড তৈরি করা হয় যা সি এর চেয়ে বেশি কার্যকর
টম হাটিন -

আমি সম্মত হই যে কখনও কখনও JITed কোডটি আরও ভাল লোকালাইজড হয়ে উঠবে যেহেতু এটি জানে যে এটি কোন প্রসেসরের উপর চলছে on তবে এটি যেহেতু "ঠিক সময়ে" তাই এটি কখনই কার্যকর হয় না এমন সমস্ত অ-স্থানীয় আশাবাদ ব্যবহার করতে সক্ষম হবে না। এছাড়াও, এটি হ্যান্ড ক্র্যাফ্টেড সি কোডটি (যা প্রসেসরটিকে অ্যাকাউন্টে নিতে পারে এবং নির্দিষ্ট প্রসেসরের জন্য কমপ্লিট করে বা কোনও ধরণের রানটাইম চেক দ্বারা আংশিকভাবে জেআইটি সুবিধাগুলি উপেক্ষা করতে পারে) এর সাথে মেলে না সক্ষম হতে পারে।
হ্রভোজে প্রেজে

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

@ স্টেফেন সি - শাখা অপ্টিমাইজেশান সম্পর্কে দুর্দান্ত পয়েন্ট, আপনি একইভাবে প্রভাব অর্জনের জন্য সি / সি ++ সংকলকগুলির সাথে স্থির পারফরম্যান্স প্রোফাইলিংও করতে পারেন could আমি আরও মনে করি যে হটস্পটটিতে অপারেশনটির দুটি পদ্ধতি রয়েছে - ডেস্কটপ অ্যাপ্লিকেশনগুলি যুক্তিসঙ্গত স্টার্টআপ সময় অর্জনের জন্য উপলব্ধ সমস্ত অপ্টিমাইজেশন ব্যবহার করবে না, যখন সার্ভার অ্যাপ্লিকেশনগুলি আরও আক্রমণাত্মকভাবে অনুকূলিত হবে। সব মিলিয়ে আপনি কিছু সুবিধা পান তবে আপনি কিছুটা আলগাও করেন।
হ্রভোজে প্রেজিয়া

4
System.arrayCopy সি ব্যবহার করে প্রয়োগ করা হয় না, যা এই উত্তরটিকে অকার্যকর করে দেয়
নিতসান ওয়াকার্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.