JavaRush /وبلاگ جاوا /Random-FA /عملیات موازی روی آرایه ها در جاوا 8 - ترجمه
billybonce
مرحله
Москва

عملیات موازی روی آرایه ها در جاوا 8 - ترجمه

در گروه منتشر شد
ترجمه مقاله
//عملیات آرایه موازی در جاوا 8 //توسط اریک برونو، 25 مارس 2014 //drdobbs.com/jvm/parallel-array-operations-in-java-8/240166287 //اریک برونو در بخش مالی و وبلاگ ها کار می کند. برای وب سایت Dr. داب
نسخه جدید جاوا تعامل موازی با آرایه‌ها را آسان‌تر می‌کند - که منجر به بهبود قابل توجه عملکرد با حداقل کدنویسی می‌شود. اکنون، اوراکل جاوا SE 8 را منتشر می کند - که از نظر زبان گام بزرگی به جلو است. یکی از ویژگی های مهم این نسخه بهبود همزمانی است که برخی از آنها در کلاس پایه java.util.Arrays ظاهر می شوند. متدهای جدیدی به این کلاس اضافه شده است که در این مقاله توضیح خواهم داد. برخی از اینها در یکی دیگر از ویژگی های جدید JDK8 استفاده می شود - lambdas. اما بیایید به کار خود بپردازیم.
Arrays.paralellSort()
بسیاری از ویژگی های parallelSort بر اساس یک الگوریتم مرتب سازی ادغام موازی است که به صورت بازگشتی یک آرایه را به قطعات تقسیم می کند، آنها را مرتب می کند و سپس آنها را به طور همزمان در یک آرایه نهایی دوباره ترکیب می کند. استفاده از آن به جای روش Arrays.sort متوالی موجود باعث بهبود عملکرد و کارایی هنگام مرتب‌سازی آرایه‌های بزرگ می‌شود. به عنوان مثال، کد زیر از sort () sequential و 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 بایت طول کشید (و مال شما به تصاویر بستگی دارد. که استفاده خواهید کرد). روش مرتب‌سازی متوالی تقریباً 3000 میلی‌ثانیه برای مرتب‌سازی آرایه در لپ‌تاپ 4 هسته‌ای من طول کشید، در حالی که روش مرتب‌سازی موازی حداکثر حدود 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 که از همزمانی و لامبدا استفاده می کند، Spliterator است که برای تکرار و تقسیم آرایه استفاده می شود. تأثیر آن به آرایه ها محدود نمی شود - همچنین برای کلاس های مجموعه و کانال های IO به خوبی کار می کند. Spliterator ها با تقسیم خودکار یک آرایه به قسمت های مختلف کار می کنند و یک 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... }
جریان - پردازش
در نهایت، از یک آرایه، می‌توانید یک شی Stream ایجاد کنید، که امکان پردازش موازی روی نمونه‌ای از داده‌ها را به‌عنوان یک کل، که به دنباله‌ای جریان تعمیم داده می‌شود، می‌دهد. تفاوت بین یک مجموعه داده و یک جریان از JDK8 جدید این است که مجموعه ها به شما اجازه می دهند با عناصر به صورت جداگانه کار کنید در حالی که یک جریان این کار را نمی کند. به عنوان مثال، با مجموعه ها، می توانید عناصر را اضافه کنید، آنها را حذف کنید و آنها را در وسط قرار دهید. دنباله Stream به شما اجازه نمی دهد عناصر جداگانه را از یک مجموعه داده دستکاری کنید، اما در عوض به شما اجازه می دهد تا عملکردهایی را روی داده ها به عنوان یک کل انجام دهید. می‌توانید عملیات مفیدی مانند استخراج فقط مقادیر خاص (نادیده گرفتن تکرارها) از یک مجموعه، عملیات تبدیل داده‌ها، یافتن حداقل و حداکثر یک آرایه، توابع کاهش نقشه (مورد استفاده در محاسبات توزیع‌شده) و سایر عملیات‌های ریاضی را انجام دهید. مثال ساده زیر از همزمانی برای پردازش آرایه ای از داده ها به صورت موازی و جمع عناصر استفاده می کند. public void streamProcessing() { int[] src = getData(); IntStream stream = Arrays.stream(src); int sum = stream.sum(); System.out.println("\nSum: " + sum); }
نتیجه
جاوا 8 قطعا یکی از مفیدترین به روز رسانی های این زبان خواهد بود. ویژگی های موازی ذکر شده در اینجا، لامبدا، و بسیاری از برنامه های افزودنی دیگر موضوع بررسی های دیگر جاوا 8 در سایت ما خواهند بود.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION