JavaRush /جاوا بلاگ /Random-UR /جاوا 8 میں صفوں پر متوازی آپریشنز - ترجمہ
billybonce
سطح
Москва

جاوا 8 میں صفوں پر متوازی آپریشنز - ترجمہ

گروپ میں شائع ہوا۔
مضمون کا ترجمہ
//جاوا 8 میں متوازی صف کے آپریشنز //ایرک برونو کے ذریعے، 25 مارچ 2014 //drdobbs.com/jvm/parallel-array-operations-in-java-8/240166287 //ایرک برونو مالیاتی شعبے اور بلاگز میں کام کرتے ویب سائٹ کے لیے ڈاکٹر ڈوبس۔
جاوا کی نئی ریلیز متوازی طور پر صفوں کے ساتھ تعامل کو آسان بناتی ہے - جس کے نتیجے میں کم از کم کوڈنگ کے ساتھ نمایاں طور پر بہتر کارکردگی ہوتی ہے۔ اب، اوریکل جاوا SE 8 جاری کر رہا ہے - جو زبان کے لحاظ سے ایک بہت بڑا قدم ہے۔ اس ریلیز کی ایک اہم خصوصیت بہتر کرنسی ہے، جن میں سے کچھ java.util.Arrays بیس کلاس میں ظاہر ہوتی ہیں۔ اس کلاس میں نئے طریقے شامل کیے گئے ہیں، جنہیں میں اس مضمون میں بیان کروں گا۔ ان میں سے کچھ کو JDK8 کی ایک اور نئی خصوصیت - lambdas میں استعمال کیا گیا ہے۔ لیکن آئیے کاروبار پر اترتے ہیں۔
Arrays.paralellSort()
parallelSort کی بہت سی خصوصیات متوازی انضمام کے الگورتھم پر مبنی ہیں جو ایک صف کو بار بار حصوں میں تقسیم کرتی ہے، ان کو ترتیب دیتی ہے، اور پھر انہیں ایک ساتھ ایک آخری صف میں دوبارہ جوڑ دیتی ہے۔ موجودہ، ترتیب وار Arrays.sort طریقہ کے بجائے اسے استعمال کرنے سے بڑی صفوں کو چھانٹتے وقت کارکردگی اور کارکردگی میں بہتری آتی ہے۔ مثال کے طور پر، نیچے کا کوڈ ترتیب وار ترتیب() اور متوازی parallelSort() کا استعمال کرتا ہے اسی ڈیٹا کی صف کو ترتیب دینے کے لیے: public class ParallelSort { public static void main(String[] args) { ParallelSort mySort = new ParallelSort(); int[] src = null; System.out.println("\nSerial sort:"); src = mySort.getData(); mySort.sortIt(src, false); System.out.println("\nParallel sort:"); src = mySort.getData(); mySort.sortIt(src, true); } public void sortIt(int[] src, boolean parallel) { try { System.out.println("--Array size: " + src.length); long start = System.currentTimeMillis(); if ( parallel == true ) { Arrays.parallelSort(src); } else { Arrays.sort(src); } long end = System.currentTimeMillis(); System.out.println( "--Elapsed sort time: " + (end-start)); } catch ( Exception e ) { e.printStackTrace(); } } private int[] getData() { try { File file = new File("src/parallelsort/myimage.png"); BufferedImage image = ImageIO.read(file); int w = image.getWidth(); int h = image.getHeight(); int[] src = image.getRGB(0, 0, w, h, null, 0, w); int[] data = new int[src.length * 20]; for ( int i = 0; i < 20; i++ ) { System.arraycopy( src, 0, data, i*src.length, src.length); } return data; } catch ( Exception e ) { e.printStackTrace(); } return null; } } جانچنے کے لیے، میں نے تصویر سے خام ڈیٹا کو صف میں لوڈ کیا، جس میں 46,083,360 بائٹس لگے (اور آپ کا انحصار تصاویر پر ہوگا۔ جسے آپ استعمال کریں گے)۔ ترتیب وار ترتیب کے طریقہ کار نے میرے 4 کور لیپ ٹاپ پر صف کو ترتیب دینے میں تقریباً 3,000 ملی سیکنڈ کا وقت لیا، جبکہ متوازی ترتیب کے طریقہ کار میں زیادہ سے زیادہ 700 ملی سیکنڈ لگے۔ متفق ہوں، ایسا اکثر نہیں ہوتا کہ زبان کی نئی اپ ڈیٹ کلاس کی کارکردگی کو 4 گنا بہتر کر دیتی ہے۔
Arrays.parallelPrefix()
parallelPrefix طریقہ ایک مخصوص ریاضیاتی فنکشن کو ایک صف کے عناصر پر اجتماعی طور پر لاگو کرتا ہے، متوازی طور پر صف کے اندر نتائج پر کارروائی کرتا ہے۔ یہ بڑی صفوں پر ترتیب وار کارروائیوں کے مقابلے جدید ملٹی کور ہارڈ ویئر پر بہت زیادہ موثر ہے۔ ڈیٹا آپریشنز کی مختلف بنیادی اقسام (مثال کے طور پر، IntBinaryOperator، DoubleBinaryOperator، LongBinaryOperator، اور اسی طرح) کے ساتھ ساتھ مختلف قسم کے ریاضیاتی آپریٹرز کے لیے اس طریقہ کے بہت سے نفاذ ہیں۔ یہاں پچھلی مثال کی طرح ایک ہی بڑی صف کا استعمال کرتے ہوئے متوازی سرنی اسٹیکنگ کی ایک مثال ہے، جو میرے 4 کور لیپ ٹاپ پر تقریباً 100 ملی سیکنڈ میں مکمل ہوئی۔ public class MyIntOperator implements IntBinaryOperator { @Override public int applyAsInt(int left, int right) { return left+right; } } public void accumulate() { int[] src = null; // accumulate test System.out.println("\nParallel prefix:"); src = getData(); IntBinaryOperator op = new ParallelSort.MyIntOperator(); long start = System.currentTimeMillis(); Arrays.parallelPrefix(src, new MyIntOperator()); long end = System.currentTimeMillis(); System.out.println("--Elapsed sort time: " + (end-start)); } ... }
Arrays.parallelSetAll()
نیا parallelSetAll() طریقہ ایک صف بناتا ہے اور کارکردگی کو بہتر بنانے کے لیے متوازی کا استعمال کرتے ہوئے، ان اقدار کو پیدا کرنے والے فنکشن کے مطابق ہر صف کے عنصر کو ایک قدر پر سیٹ کرتا ہے۔ یہ طریقہ لیمبڈاس پر مبنی ہے (جسے دوسری زبانوں میں "بندش" کہا جاتا ہے) (اور، ہاں، یہ مصنف کی غلطی ہے، کیونکہ لیمبڈاس اور بندیاں الگ الگ چیزیں ہیں) ، اور جو JDK8 کی ایک اور نئی خصوصیت ہے جس پر ہم مستقبل کے مضامین میں بحث کریں گے۔ یہ نوٹ کرنا کافی ہوگا کہ لیمبڈاس، جس کی ترکیب کو --> آپریٹر کے ذریعے پہچاننا آسان ہے، تیر کے بعد دائیں جانب سے تمام عناصر کے لیے ایک آپریشن انجام دیتا ہے۔ نیچے دیے گئے کوڈ کی مثال میں، کارروائی صف میں موجود ہر عنصر کے لیے کی جاتی ہے، جس کی ترتیب i۔ Array.parallelSetAll() سرنی عناصر پیدا کرتا ہے۔ مثال کے طور پر، مندرجہ ذیل کوڈ بے ترتیب عددی اقدار کے ساتھ ایک بڑی صف کو بھرتا ہے: public void createLargeArray() { Integer[] array = new Integer[1024*1024*4]; // 4M Arrays.parallelSetAll( array, i -> new Integer( new Random().nextInt())); } ایک زیادہ پیچیدہ سرنی عنصر جنریٹر بنانے کے لیے (مثال کے طور پر، وہ جو حقیقی دنیا کے سینسر سے ریڈنگ کی بنیاد پر اقدار پیدا کرے گا)، آپ اس سے ملتا جلتا کوڈ استعمال کر سکتے ہیں۔ درج ذیل: public void createLargeArray() { Integer[] array = new Integer[1024*1024*4]; // 4M Arrays.parallelSetAll( array, i -> new Integer( customGenerator(getNextSensorValue()))); } public int customGenerator(int arg){ return arg + 1; // some fancy formula here... } public int getNextSensorValue() { // Just random for illustration return new Random().nextInt(); } ہم getNextSensorValue کے ساتھ شروع کریں گے، جو حقیقت میں سینسر (مثال کے طور پر، تھرمامیٹر) سے اس کی موجودہ قیمت واپس کرنے کو کہے گا۔ یہاں، مثال کے طور پر، ایک بے ترتیب قدر پیدا ہوتی ہے۔ درج ذیل customGenerator() طریقہ آپ کے منتخب کردہ کیس کی بنیاد پر منتخب منطق کا استعمال کرتے ہوئے عناصر کی ایک صف تیار کرتا ہے۔ یہاں ایک چھوٹا سا اضافہ ہے، لیکن حقیقی معاملات کے لیے، یہ کچھ زیادہ پیچیدہ ہوگا۔
Spliterator کیا ہے؟
Arrays کلاس میں ایک اور اضافہ جو concurrency اور lambdas کا استعمال کرتا ہے Spliterator ہے، جو کہ ایک صف کو دوبارہ کرنے اور تقسیم کرنے کے لیے استعمال ہوتا ہے۔ اس کا اثر صرف صفوں تک ہی محدود نہیں ہے - یہ کلیکشن کلاسز اور IO چینلز کے لیے بھی اچھا کام کرتا ہے۔ Spliterators خود بخود ایک صف کو مختلف حصوں میں تقسیم کر کے کام کرتے ہیں، اور ان منسلک ذیلی ریزوں پر آپریشن کرنے کے لیے ایک نیا Spliterator انسٹال ہوتا ہے۔ اس کا نام Iterator سے بنا ہے، جو اس کے حرکت پذیری کے کام کو حصوں میں تقسیم کرتا ہے۔ اپنے اسی ڈیٹا کا استعمال کرتے ہوئے، ہم اپنی صف پر ایک تقسیم شدہ عمل کو اس طرح انجام دے سکتے ہیں: اس طرح ڈیٹا پر ایکشن کرنا متوازی کا فائدہ اٹھاتا ہے۔ آپ سپلٹر پیرامیٹرز بھی سیٹ کر سکتے ہیں، جیسے کہ ہر ذیلی کا کم از کم سائز۔ public void spliterate() { System.out.println("\nSpliterate:"); int[] src = getData(); Spliterator spliterator = Arrays.spliterator(src); spliterator.forEachRemaining( n -> action(n) ); } public void action(int value) { System.out.println("value:"+value); // Perform some real work on this data here... }
سٹریم - پروسیسنگ
آخر میں، ایک Array سے، آپ ایک Stream آبجیکٹ بنا سکتے ہیں، جو کہ مجموعی طور پر ڈیٹا کے نمونے پر متوازی پروسیسنگ کی اجازت دیتا ہے، جو کہ ایک سلسلہ کی ترتیب میں عمومی ہے۔ ڈیٹا اکٹھا کرنے اور نئے JDK8 سے ایک سٹریم کے درمیان فرق یہ ہے کہ مجموعہ آپ کو عناصر کے ساتھ انفرادی طور پر کام کرنے کی اجازت دیتا ہے جب کوئی سلسلہ نہیں کرتا ہے۔ مثال کے طور پر، مجموعوں کے ساتھ، آپ عناصر کو شامل کر سکتے ہیں، انہیں ہٹا سکتے ہیں اور درمیان میں ڈال سکتے ہیں۔ سٹریم کی ترتیب آپ کو ڈیٹا سیٹ سے انفرادی عناصر میں ہیرا پھیری کرنے کی اجازت نہیں دیتی ہے، بلکہ آپ کو مجموعی طور پر ڈیٹا پر افعال انجام دینے کی اجازت دیتی ہے۔ آپ اس طرح کے مفید آپریشنز انجام دے سکتے ہیں جیسے کسی سیٹ سے صرف مخصوص قدریں نکالنا (دوہرائی کو نظر انداز کرنا)، ڈیٹا ٹرانسفارمیشن آپریشنز، کم از کم اور زیادہ سے زیادہ ایک صف کا پتہ لگانا، نقشہ کم کرنے کے فنکشنز (تقسیم شدہ کمپیوٹنگ میں استعمال ہوتے ہیں)، اور دیگر ریاضیاتی آپریشنز۔ درج ذیل سادہ مثال متوازی طور پر ڈیٹا کی ایک صف کو پروسیس کرنے اور عناصر کو جمع کرنے کے لیے ہم آہنگی کا استعمال کرتی ہے۔ public void streamProcessing() { int[] src = getData(); IntStream stream = Arrays.stream(src); int sum = stream.sum(); System.out.println("\nSum: " + sum); }
نتیجہ
Java 8 یقینی طور پر زبان کے لیے سب سے مفید اپ ڈیٹس میں سے ایک ہوگا۔ متوازی خصوصیات جن کا یہاں ذکر کیا گیا ہے، لیمبڈاس، اور بہت سی دوسری ایکسٹینشن ہماری سائٹ پر جاوا 8 کے دیگر جائزوں کا موضوع ہوں گی۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION