ورود

View Full Version : آموزش: نکات و اصول مهم در برنامه نویسی Java/Android



Yousha
دوشنبه 30 شهریور 1394, 13:26 عصر
حذف شد..........

ravand
سه شنبه 31 شهریور 1394, 09:34 صبح
از سرعت اجرای برنامه حرف زدید. من وقتی به برنامه ی جاوام یه فونت میدم مثلا یکان. نمیدونم چرا کلی طول میکشه تا برنامه اجرا بشه؟ من برای حل این مشکل باید چکار کنم؟

E G A L E
شنبه 04 مهر 1394, 18:48 عصر
میشه با استدلال توضیح بدین چرا تاکیید شده متدها رو استاتیک تعریف شود؟

Yousha
شنبه 04 مهر 1394, 19:53 عصر
این مربوط میشه به مباحث java internals. در صورتی که با این مبحث آشنا باشی این قضیه رو بخوبی متوجه میشی:

اول اینکه متدهای static نمی تونن overriden بشن و هیچ نیازی هم ندارن تا از نظر Nullity (یا همون Null reference) بررسی بشن. و از اونجایی که JVM/DM برای بهینه کردن متد های غیر استاتیک عملیات بسیار زیادی رو انجام میده(از جمله nullity check)، این مورد شامل حال متد های static نمیشه.

نکته بعدی در مورد byte-code هاست، call شدن متدهای غیراستاتیک توسط ساخت بایت کد INVOKEVIRTUAL (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual), INVOKEINTERFACE (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface) یا INVOKESPECIAL (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial)انجام میشه، درحالی که call شدن متدهای استاتیک توسط ساخت INVOKESTATIC (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic) انجام میشه.

سوم اینکه متد استاتیک polymorphic نیست، پس JVM/DVM نیازی به تصمیم گیری و پردازش های مختلف برای پیدا کردن کد واقعی نداره.

و آخرین و مهمترین اینکه برای استفاده از متدهای static نیازی به ساخت شی نیست! پس مصرف کمتر حافظه، سرعت بیشتر. (چیزی که در device های کوچیک بسیار اهمیت داره)
(نکته های مشابه (http://www.javaperformancetuning.com/tips/final.shtml))


اما این تفاوت در حد 10% هه... اگر واقاً لازمه و نیاز داری می تونی ازش پیروی کنی.

-سیّد-
یک شنبه 05 مهر 1394, 01:32 صبح
سلام
ممنون از نکاتی که گفتید.
اما بعضی‌هاش یه مقدار مشکوک به نظر می‌رسه. خیلی خوب می‌شد اگه برای همه‌اش reference می‌ذاشتید. مثلاً:


24- طبق گفته گوگل، حتاالمکان بصورت مستقیم/directly فیلد های اشیا رو فراخوانی کنید، بجای استفاده از setter/getter.

این یه مقدار عجیب به نظر می‌رسه، و فکر نمی‌کنم درست باشه. دلیلش هم اینه که JIT انقدر پیشرفته هست که بتونه setter/getter رو به راحتی تشخیص بده و با دسترسی مستقیم جایگزینش کنه. مگر این که JIT توی Dalvik از این کارها بلد نباشه!
یا مثلاً این:


25- بر طبق benchmark های موجود، در اندروید، پردازش داده نوع float تقریباً 2 برابر کندتر از پردازش داده نوع int هست، درحالیه که در مورد داده نوع double اینطور نیست. پس در بیشتر موارد، نوع double جایگزین خوبی برای نوع float هستش.

خیلی خوبه که یه پیوند به benchmark های موجود بذارید که آدم بدونه منبع این حرف کجاس.
یا این:


32- طبق گفته گوگل، حتاالمکان از حلقه enhanced for (یا همون for each) بجای حلقه for استفاده کنید.
اینکار سرعت پردازش حلقه رو تا 3 برابر افزایش میده.

این رو هم خیلی خوب بود با منبع می‌ذاشتید.

کلاً من روی منبع خیلی حساسم! :)

Yousha
یک شنبه 05 مهر 1394, 10:57 صبح
شما که دنبال منبع و سند و مدرکی، حداقل زحمت گشتن به خودت میدادی...
و خب خوب شد حداقل نوشتم طبق گفته گوگل، نه طبق گفته Yousha:


اما بعضی‌هاش یه مقدار مشکوک به نظر می‌رسه. خیلی خوب می‌شد اگه برای همه‌اش reference می‌ذاشتید.

این یه مقدار عجیب به نظر می‌رسه، و فکر نمی‌کنم درست باشه. دلیلش هم اینه که JIT انقدر پیشرفته هست که بتونه setter/getter رو به راحتی تشخیص بده و با دسترسی مستقیم جایگزینش کنه. مگر این که JIT توی Dalvik از این کارها بلد نباشه!
منبع:
http://developer.android.com/training/articles/perf-tips.html#GettersSetters

http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/



بر طبق benchmark های موجود، در اندروید، پردازش داده نوع float تقریباً 2 برابر کندتر از پردازش داده نوع int هست، درحالیه که در مورد داده نوع double اینطور نیست. پس در بیشتر موارد، نوع double جایگزین خوبی برای نوع float هستش.

خیلی خوبه که یه پیوند به benchmark های موجود بذارید که آدم بدونه منبع این حرف کجاس.
منبع:
http://developer.android.com/training/articles/perf-tips.html#AvoidFloat



طبق گفته گوگل، حتاالمکان از حلقه enhanced for (یا همون for each) بجای حلقه for استفاده کنید.
اینکار سرعت پردازش حلقه رو تا 3 برابر افزایش میده.
منبع:
http://developer.android.com/training/articles/perf-tips.html#Loops

-سیّد-
یک شنبه 05 مهر 1394, 11:54 صبح
شما که دنبال منبع و سند و مدرکی، حداقل زحمت گشتن به خودت میدادی...

:)
خوب دوست گرامی، این وظیفه‌ی شماست که وقتی از یکی نقل قول می‌کنی، منبعش رو هم بیاری. نمی‌شه که من بیام یه سری اطلاعات بدون منبع بنویسم، بگم هر کی می‌خواد خودش بره بگرده منبعش رو پیدا کنه!
وقتی اینطوری می‌نویسی که «طبق گفته‌ی گوگل ...»، یاد همچین چیزایی می‌افتم:
http://www.hoax-slayer.com/black-in-white-house-virus-hoax.shtml


It is the worst virus announced by CNN. A new virus has been discovered Recently it has been classified by Microsoft as the virus most destructive ever. This virus was discovered yesterday afternoon By McAfee.

و البته نسخه‌ی فارسیش که توی ایمیل‌ها می‌چرخه! خوب دلیل این که همچین ایمیل‌های خالی‌بندی‌ای این همه می‌چرخه، اینه که کسی به منبع اهمیت نمی‌ده! وقتی می‌گم منبعش رو بدید، برای اینه که خواننده بتونه بین خالی‌بندی (یا حرف اشتباه) و حرف مستند و مستدل تفاوت قائل بشه.



و خب خوب شد حداقل نوشتم طبق گفته گوگل، نه طبق گفته Yousha:



منبع:
http://developer.android.com/training/articles/perf-tips.html#GettersSetters

http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/




منبع:
http://developer.android.com/training/articles/perf-tips.html#AvoidFloat



منبع:
http://developer.android.com/training/articles/perf-tips.html#Loops
ممنون بابت منابع. خیلی خوب می‌شد که منابع رو توی متن اصلی می‌ذاشتید که همه استفاده کنن. کلاً منبع چیز خوبیه! در واقع منبع معتبر دادن، اعتبار حرف شما رو بالا می‌بره (همونطور که الان اعتبار این نوشته‌ی شما به خاطر استناد به android.com خیلی بالا می‌ره).

اولاً که هنوز من در عجبم که چرا اندروید نمی‌تونه getter/setter رو توسط JIT مدیریت کنه (این کار توی جاوا به خوبی انجام می‌شه و استفاده از getter/setter تقریباً هیچ هزینه‌ای نداره، و با توجه به این که اینجا انجمن جاوا استاندارد هست، این بخش از نکات در مورد جاوا صحیح نیست).
ثانیاً بخش دوم نکته‌ی ۲۵ صحیح نیست:


25- بر طبق benchmark های موجود، در اندروید، پردازش داده نوع float تقریباً 2 برابر کندتر از پردازش داده نوع int هست، درحالیه که در مورد داده نوع double اینطور نیست. پس در بیشتر موارد، نوع double جایگزین خوبی برای نوع float هستش.

چیزی که توی منبع اصلی اومده اینه: ( http://developer.android.com/training/articles/perf-tips.html#AvoidFloat )


As a rule of thumb, floating-point is about 2x slower than integer on Android-powered devices.
In speed terms, there's no difference between float and double on the more modern hardware. Space-wise,double is 2x larger. As with desktop machines, assuming space isn't an issue, you should prefer double tofloat.

اون طور که اینجا نوشته، سرعت double با float فرقی نمی‌کنه، نه این که سرعت double با int فرقی نمی‌کنه. بنابراین این بخش از حرف شما صحیح نیست:


درحالیه که در مورد داده نوع double اینطور نیست.


در نهایت هم این که به نظرم رسید که شما احساس کردید من دارم به شما حمله می‌کنم که اینطور جواب دادید! من فقط دنبال این بودم که شما اعتبار نوشته‌تون رو با اوردن منبع بالاتر ببرید که بقیه بهتر بتونن استفاده کنن، هدفم تخریب شما نیست!

محمد فدوی
یک شنبه 05 مهر 1394, 13:20 عصر
شما که دنبال منبع و سند و مدرکی، حداقل زحمت گشتن به خودت میدادی...
پیشنهاد من اینه که به جای گله کردن، خوشحال باشید از اینکه پستتون توسط فردی خونده شده که فنی به موضوع نگاه می‌کنه. درسته؛ من نوعی اگر حرفی رو می‌زنم باید با منبع باشه و اگر هم کسی ازم درخواست منبع کرد نباید ناراحت شم بلکه باید ازش تشکر کنم.

از این گذشته، اولا ممنونم که این موضوع خوب رو ایجاد کردی. مطالب مفیدی توش نوشتی و امیدوارم ادامه‌ش هم بدی.


منبع:
http://developer.android.com/trainin...GettersSetters (http://developer.android.com/training/articles/perf-tips.html#GettersSetters)

http://blog.leocad.io/why-you-should...rs-on-android/ (http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/)
اما در مورد Getter/Setterها، اولین چیزی که باید بهش توجه کنیم اینه که این تکنیک مزیتش به همه ثابت‌شده‌ست. چرا که به ناچار توی برنامه‌نویسی شیءگرا ما به مسائلی نیاز داریم که لازمه‌شون استفاده از این متدهاست. مهمترین اون‌ها ارث‌بری، طراحی لایه‌ی انتزاعی (Abstract) و جدا کردن پیاده‌سازی از استفاده هستن. خب دسترسی مستقیم به یه خصوصیت (Property) این نیازها رو برطرف نمی‌کنه و فریمورک‌های مختلف تکنیک‌های مختلفی برای رفع این نیاز دارن... جاوا هم از Getter/Setterها استفاده می‌کنه. از نظر من تفاوت کارایی بین استفاده از متدهای Getter/Setter با دسترسی مستقیم هرچقدر که باشه باعث نمی‌شه اونا رو کنار بذارم.
توی منبعی هم که از Android Developers گذاشتید اشاره شده که استفاده از این متدها داخل خود کلاس کار درستی نیست و صحیح هم هست. مثلا وقتی توی برنامه‌نویسی اندروید توی یه Activity یه سری کامپوننت داریم بدون شک برای دسترسی به اون کامپوننت‌ها از Getter/Setter استفاده نمی‌کنیم:


It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.



شاید بعضیا ترجیح بدن مابین کلاس‌هایی که خودشون می‌نویسن هم بصورت مستقیم به اشیاء دسترسی پیدا کنن... شاید در بیلد اول نرم‌افزار هم به مشکل نخورن، اما بدون شک این‌کار روند توسعه‌ی نرم‌افزار رو در آینده خیلی کند می‌کنه به دلیل اینکه چنین نرم‌افزاری کانسپت‌های توسعه‌ی نرم‌افزار شیءگرا رو پیاده‌سازی نکرده و اگر یه مدیرپروژه‌ی خوب بالای سر پروژه باشه صددرصد جلوی چنین کاری رو می‌گیره! (هرچند اکثر پروژه‌های ایرانی بصورت فریلنسی انجام می‌شن)

خیلی طولانی شد. در نهایت با توجه به لینک بنچمارکی که شما گذاشتید برای مقایسه بین این دو روش، هرچند تفاوت‌ها کم نبود ولی از نظر من قابل پذیرش بود و منم پیشنهاد می‌کنم همیشه از Getter/Setterها استفاده کنید به جز وقتی که می‌خواید توی خود اون کلاس به خصوصیاتش دسترسی پیدا کنید.

Yousha
یک شنبه 05 مهر 1394, 13:46 عصر
In speed terms, there's no difference between float and double on the more modern hardware
من در مورد گوشی شما که اندرویدش 4 یا 5 هه حرف نمی زنم، درباره اندرود 2.3.3 به بالا حرف زدم که هنوزم خیلی ها دارن. ازجمله خودم



اگر یه مدیرپروژه‌ی خوب بالای سر پروژه باشه صددرصد جلوی چنین کاری رو می‌گیره!
اون مدیر پروژه نیست که اینکارو میکنه، برنامه نویس ارشد هستش که اینکارو میکنه.
در ضمن صحبت و تمرکز من در اینجا روی dvm و اندرویده، و نه Pure java / jvm


این مقاله رو هم دیروز ننوشتم، مال یک سال پیشه. ولی چند روز پیش اینجا گذاشتمش.
پس زیاد درموردش هوشمند نباشید و نشکافیدش!

pbm_soy
یک شنبه 05 مهر 1394, 14:39 عصر
در نکات جالبی بود ارزشمند است اگر بحث منابع را نادیده بگیریم!
البته من هم میگم ذکر منبع و دیلیل مدرک ارزش کار را بالاتر میبرد
تو همین سایت کم نبوده که برخی از دوستان خیلی راحت میگن فلان زبان برای فلان کار بدرد نمیخورد! از طرف میپرسی برچه اساسی این حرف را میگی؟! برمیگرده جواب میده "اصلا شما تاحالا تو فلان زبان فلان کار انجام دادی؟"!!! با چنین جوابی دیگران را از نوشتن و پاسخ دادن منصرف میکند و شاید ایشون تا مدتها با یک فکر یا نتیجه گیری اشتباه به کارش ادامه دهد!
در حالی که گفته ایشون کاملا بی پایه و اساس است و کلا اشتباه فکر میکردن و چیزی که نوشتن را میتوانستن به روشهای دیگر ویا الگوریتمهای دیگر بنویسند تا آن فلان زبان هم در این زمینه قدرت خودش را نشان دهد!

-سیّد-
یک شنبه 05 مهر 1394, 14:40 عصر
من در مورد گوشی شما که اندرویدش 4 یا 5 هه حرف نمی زنم، درباره اندرود 2.3.3 به بالا حرف زدم که هنوزم خیلی ها دارن. ازجمله خودم

‫‫خوب اونجا چیزی درباره‌ی این نگفته که روی گوشی‌های قدیمی‌تر، سرعت double بیشتره یا float. من هم نمی‌دونم! و البته برام سؤال پیش اومده که چرا سرعت double باید از float بیشتر باشه؟ (یعنی می‌شه اینطور نتیجه‌گیری کرد که سرعت long هم از int بیشتره؟) ممنون می‌شم اگه کسی برام توضیح بده تا قضیه رو بفهمم.




این مقاله رو هم دیروز ننوشتم، مال یک سال پیشه. ولی چند روز پیش اینجا گذاشتمش.
پس زیاد درموردش هوشمند نباشید و نشکافیدش!

:)
ما بالاخره نفهمیدیم! این مقاله‌ای که شما نوشتید به درد الان می‌خوره یا نه؟ اگه نمی‌خوره، خوب برای چی گذاشتیدش؟! اگه می‌خوره، خوب چه اشکالی داره که یه مقدار اینجا به قول شما بشکافیمش؟ خود من خیلی خوشحال می‌شم اگه یه چیزی که می‌نویسم غلط باشه اینجا بهم بگن.

و در ضمن، همونطور که آقای فدوی گفتن، در مجموع مطالب مفیدی بود، خود من هم استفاده کردم. فقط یه جاهاییش برام سؤال بود که مطرح کردم.