Performance Optimization with Java.time API

Java Technologies - জাভা টাইম প্যাকেজ (Java.time Package)
78
78

Java 8java.time প্যাকেজের সূচনা কার্যকরভাবে সময় এবং তারিখের সাথে কাজ করার জন্য অনেক শক্তিশালী ক্লাস এবং ফিচার সরবরাহ করেছে। তবে, যখন আপনি সময় এবং তারিখের সাথে প্রচুর পরিমাণে কাজ করছেন, তখন পারফরম্যান্স অপটিমাইজেশন খুবই গুরুত্বপূর্ণ হয়ে ওঠে। সঠিকভাবে ডিজাইন করা কোড আপনার অ্যাপ্লিকেশনের গতি এবং স্কেলেবিলিটি উন্নত করতে সাহায্য করতে পারে।

এই প্যাকেজের Instant, LocalDateTime, ZonedDateTime, Duration, Period এবং DateTimeFormatter ক্লাসগুলির ব্যবহার করে পারফরম্যান্স অপটিমাইজেশন করতে কয়েকটি কৌশল এবং পদ্ধতি সম্পর্কে আলোচনা করা হবে।

Java.time API Performance Optimization Strategies

  1. Avoiding Repeated DateTimeFormatter Object Creation

    DateTimeFormatter ক্লাসটি তারিখ এবং সময় স্ট্রিং পার্সিং (parsing) বা ফরম্যাটিং (formatting) করার জন্য ব্যবহৃত হয়। প্রতিবার ফরম্যাটিং বা প্যার্সিং করার সময় নতুন DateTimeFormatter অবজেক্ট তৈরি করা হলে, এটি একটি খারাপ পারফরম্যান্স প্যাটার্ন হতে পারে, বিশেষত যখন একই ফরম্যাট বারবার ব্যবহার করা হয়।

    Optimization: Use Static or Shared Formatter Instances

    • Static অথবা Shared Formatter Instances ব্যবহার করুন, যাতে একই Formatter পুনঃব্যবহার হয় এবং এটি বারবার নতুন ইনস্ট্যান্স তৈরির প্রয়োজনীয়তা দূর করে।

    Example:

    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class DateTimeFormatterOptimization {
        // Use a static DateTimeFormatter
        private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
    
            // Reusing the same formatter to format multiple times
            String formattedDate = now.format(formatter);
            System.out.println(formattedDate);
        }
    }
    

    Why It’s Efficient:

    • এখানে DateTimeFormatter একটি static ফিল্ড হিসেবে ব্যবহার করা হয়েছে, তাই প্রতিবার ফরম্যাট করতে নতুন ইনস্ট্যান্স তৈরি করার প্রয়োজন নেই।

  1. Avoiding Frequent ZonedDateTime and LocalDateTime Conversions

    ZonedDateTime এবং LocalDateTime ক্লাসগুলির মধ্যে কনভার্সন করা সময়ের মধ্যে ZoneId ব্যবহার করে টাইমজোনের হিসাবও করতে হতে পারে, যা খরচ বহুল হতে পারে। যদি একই টাইমজোনে কাজ করা যায়, তবে বারবার কনভার্সন করার পরিবর্তে এটি অপটিমাইজ করা যেতে পারে।

    Optimization: Use Consistent ZoneId

    • একটি নির্দিষ্ট টাইমজোনের মধ্যে কাজ করুন এবং টাইমজোন কনভার্সন থেকে পরিত্রাণ পান।

    Example:

    import java.time.LocalDateTime;
    import java.time.ZonedDateTime;
    import java.time.ZoneId;
    
    public class TimeConversionOptimization {
        public static void main(String[] args) {
            ZoneId zone = ZoneId.of("America/New_York");
    
            // Using ZonedDateTime directly to avoid conversion
            ZonedDateTime zonedDateTime = ZonedDateTime.now(zone);
            System.out.println("Current Time in New York: " + zonedDateTime);
    
            // Convert to LocalDateTime (avoid frequent conversions)
            LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
            System.out.println("Converted LocalDateTime: " + localDateTime);
        }
    }
    

    Why It’s Efficient:

    • এখানে ZonedDateTime সরাসরি ZoneId ব্যবহার করে তৈরি করা হয়েছে এবং এরপর LocalDateTime কনভার্সন করা হয়েছে, যা বারবার টাইমজোন কনভার্সন করতে বাধা দেয়।

  1. Use Duration and Period Efficiently

    Duration এবং Period ক্লাসগুলো সময়ের মধ্যে পার্থক্য নির্ণয় এবং সময়কাল হিসাব করতে ব্যবহৃত হয়। তবে যদি খুব বড় সময় ব্যবধানের জন্য একে ব্যবহার করা হয়, তাহলে এটি কিছুটা অতিরিক্ত খরচ তৈরি করতে পারে। Duration সেকেন্ড এবং মিলিসেকেন্ড হিসেবে ব্যবহৃত হলেও Period বছর, মাস, দিন হিসেবে ব্যবহৃত হয়, যা বড় সময় ব্যবধানের জন্য বেশি উপযুক্ত।

    Optimization: Use Duration for Smaller Time Units, Period for Larger Units

    • Duration ব্যবহার করুন ছোট সময় ব্যবধানের জন্য (যেমন সেকেন্ড, মিনিট) এবং Period বড় সময় ব্যবধানের জন্য (যেমন বছর, মাস)।

    Example:

    import java.time.Duration;
    import java.time.LocalDateTime;
    
    public class DurationPeriodOptimization {
        public static void main(String[] args) {
            LocalDateTime start = LocalDateTime.of(2024, 1, 1, 10, 0, 0);
            LocalDateTime end = LocalDateTime.of(2024, 1, 1, 12, 30, 0);
    
            // Use Duration for smaller time difference (hours, minutes, seconds)
            Duration duration = Duration.between(start, end);
            System.out.println("Duration: " + duration.toMinutes() + " minutes");
    
            // Use Period for larger time difference (days, months, years)
            java.time.Period period = java.time.Period.between(start.toLocalDate(), end.toLocalDate());
            System.out.println("Period: " + period.getDays() + " days");
        }
    }
    

    Why It’s Efficient:

    • Duration ক্লাস সেকেন্ড এবং মিনিটের হিসাবের জন্য উপযুক্ত এবং Period ক্লাস দীর্ঘ সময়ের জন্য (যেমন দিন, মাস, বছর) ব্যবহৃত হয়, যা পারফরম্যান্স অপটিমাইজেশনে সহায়ক।

  1. Avoid Repeated LocalDateTime and ZonedDateTime Parsing

    LocalDateTime.parse() এবং ZonedDateTime.parse() মেথডগুলো স্ট্রিং থেকে সময় প্যার্স করতে ব্যবহৃত হয়, তবে যদি একটি নির্দিষ্ট ফরম্যাটের স্ট্রিং পুনরায় প্যার্স করা হয়, তাহলে এটি পারফরম্যান্স এ সমস্যা তৈরি করতে পারে।

    Optimization: Cache DateTimeFormatter Instances

    • DateTimeFormatter কে ক্যাশ করুন যাতে প্রতিবার নতুন প্যার্সার তৈরি করতে না হয়।

    Example:

    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class ParsingOptimization {
        private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
        public static void main(String[] args) {
            String dateString = "2024-12-23 10:30:00";
    
            // Use cached DateTimeFormatter for efficient parsing
            LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
            System.out.println("Parsed DateTime: " + dateTime);
        }
    }
    

    Why It’s Efficient:

    • DateTimeFormatter ক্যাশ করে ব্যবহারের ফলে প্রতিবার নতুন DateTimeFormatter ইনস্ট্যান্স তৈরি করা থেকে রক্ষা পাওয়া যায়, যা পারফরম্যান্সে সাহায্য করে।

  1. Avoid Using System.currentTimeMillis() for Time Calculations

    System.currentTimeMillis() হল সিস্টেমের বর্তমান সময় (মিলিসেকেন্ডে) পেতে ব্যবহৃত একটি মেথড, তবে এটি শুধুমাত্র Unix epoch time (1970-01-01 থেকে বর্তমান সময়) দেয় এবং কোনো টাইমজোন সম্পর্কিত হিসাব বা DST পরিবর্তন সমর্থন করে না।

    Optimization: Use Instant.now() or ZonedDateTime.now() Instead

    • Instant.now() বা ZonedDateTime.now() ব্যবহার করুন, যা বর্তমান সময় এবং টাইমজোনের সাথে কাজ করতে পারে।

    Example:

    import java.time.Instant;
    
    public class TimeMillisOptimization {
        public static void main(String[] args) {
            // Using Instant instead of System.currentTimeMillis()
            Instant now = Instant.now();
            System.out.println("Current time (Instant): " + now);
        }
    }
    

    Why It’s Efficient:

    • Instant.now() System.currentTimeMillis() এর তুলনায় আরো সঠিক, কারণ এটি টাইমজোন এবং DST-এফেক্ট সমর্থন করে।

  1. Caching: DateTimeFormatter ইন্সট্যান্সগুলো ক্যাশ করুন যাতে প্রতিবার নতুন ইনস্ট্যান্স তৈরি করতে না হয়।
  2. Use Duration and Period Wisely: ছোট সময় ব্যবধানের জন্য Duration এবং বড় সময় ব্যবধানের জন্য Period ব্যবহার করুন।
  3. Avoid Repeated Parsing: প্যার্সিং অপটিমাইজ করতে DateTimeFormatter ক্যাশ করুন এবং পুনরায় স্ট্রিং প্যার্স করার পরিহার করুন।
  4. Use Instant.now() and ZonedDateTime.now(): সিস্টেমের টাইম নিয়ে কাজ করার জন্য Instant.now() এবং ZonedDateTime.now() ব্যবহার করুন, যা DST এবং টাইমজোন পরিবর্তনগুলি সঠিকভাবে ম্যানেজ করে।

এই Java.time API ব্যবহার করে সময় সম্পর্কিত অপটিমাইজেশনগুলি কোডের পারফরম্যান্স উন্নত করতে সহায়ক হবে, বিশেষ করে যখন বড় ডেটা সেট বা টাইম-ডিপেন্ডেন্ট অপারেশনগুলি ম্যানেজ করতে হবে।

Content added By

Java.time API এর Performance Features

84
84

Java 8 থেকে java.time প্যাকেজটি প্রবর্তিত হয়েছিল এবং এটি তারিখ, সময়, টাইমজোন, এবং সম্পর্কিত টাইম স্ট্যাম্পের হিসাবের জন্য একটি শক্তিশালী API প্রদান করে। java.time প্যাকেজের API গুলো উন্নত পারফরম্যান্স, নির্ভুলতা এবং ব্যবহারকারীর প্রয়োজনে বিভিন্ন সময় সম্পর্কিত সমস্যা সমাধানে সাহায্য করে। এটি java.util.Date এবং java.util.Calendar ক্লাসগুলোর তুলনায় আরও কার্যকরী এবং দ্রুত।

এখানে আমরা Java Time API-এর পারফরম্যান্স অপটিমাইজেশন ফিচার্স সম্পর্কে আলোচনা করব।


Java Time API এর Performance Features

  1. Immutable Objects:
    • Immutable অবজেক্টগুলি ব্যবহৃত হয় যা মান পরিবর্তন করতে পারে না। java.time প্যাকেজের ক্লাসগুলি যেমন LocalDate, LocalTime, ZonedDateTime, Duration ইত্যাদি সকলই immutable, যার মানে হল যে একটি অবজেক্ট তৈরি করার পর তার মান পরিবর্তন করা সম্ভব নয়। এর ফলে thread safety উন্নত হয় এবং performance সঠিকভাবে ম্যানেজ করা যায়।
    • Immutable objects তৈরি করলে ডেটার মিউটেশন রোধ করা যায় এবং এতে পারফরম্যান্স কমে যাওয়ার সম্ভাবনা থাকে না।

Example of Immutable LocalDate:

import java.time.LocalDate;

public class ImmutableExample {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2024, 12, 23);
        System.out.println("Original Date: " + date);
        
        // Adding days creates a new instance without changing the original one
        LocalDate newDate = date.plusDays(5);
        System.out.println("New Date after adding 5 days: " + newDate);
        System.out.println("Original Date (unchanged): " + date);
    }
}

Output:

Original Date: 2024-12-23
New Date after adding 5 days: 2024-12-28
Original Date (unchanged): 2024-12-23
  • এখানে LocalDate ক্লাসটি immutable, এবং যখন plusDays(5) ব্যবহার করা হয়েছে, এটি নতুন একটি অবজেক্ট তৈরি করেছে, পুরোনো অবজেক্টটি অপরিবর্তিত থাকে।

  1. Efficient Memory Management:
    • java.time API ক্লাসগুলির মধ্যে অনেকগুলি value-based এবং immutable হওয়ায় memory-এর ব্যবস্থাপনা অনেক উন্নত। টাইমস্ট্যাম্পের হিসাব এবং সময়ের পরিবর্তন করার সময় Java Time API এ memory allocation খুবই কার্যকরী, কারণ new instance creation এর মাধ্যমে পুরোনো অবজেক্টগুলি মুছে ফেলা হয়।
  2. Thread Safety:
    • Thread safety উন্নত করার জন্য Java Time API মূলত immutable objects ব্যবহার করে, যা একই সময়ে একাধিক থ্রেড দ্বারা নিরাপদে ব্যবহৃত হতে পারে। অতএব, যেহেতু প্রতিটি অবজেক্ট অপরিবর্তিত থাকে, এটি একাধিক থ্রেডের মধ্যে শেয়ার করা যায়, যেকোনো পরিবর্তন বা শেয়ার করার সমস্যা ছাড়াই।
    • একাধিক থ্রেডে কাজ করার সময় পুরোনো Date এবং Calendar ক্লাসে সমস্যা হতে পারে (যেহেতু তারা mutable), কিন্তু java.time API এই ধরনের সমস্যা এড়াতে সাহায্য করে।

  1. Efficient Date-Time Calculations:
    • Java Time API বিভিন্ন তারিখ ও সময় সম্পর্কিত হিসাব (যেমন দিন, মাস, বছর যোগ করা বা বিয়োগ করা) দ্রুত এবং নির্ভুলভাবে করে। সময় গণনা করার জন্য এটি উচ্চ কার্যক্ষমতাসম্পন্ন পদ্ধতি ব্যবহার করে, যেমন Duration, Period বা ChronoUnit ক্লাসের মাধ্যমে।
    • Duration এবং Period ক্লাসগুলি আপনাকে দিন, মাস, বা ঘণ্টার মতো নির্দিষ্ট একক ব্যবহার করে টাইম ক্যালকুলেশন করার সুবিধা দেয় এবং এটি দ্রুত সময়ের হিসাব করে।

Example: Using ChronoUnit for Time Calculations:

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class TimeCalculationExample {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2024, 1, 1);
        LocalDate end = LocalDate.of(2024, 12, 31);
        
        // Calculate days between two dates
        long daysBetween = ChronoUnit.DAYS.between(start, end);
        System.out.println("Days between: " + daysBetween);
        
        // Calculate months between two dates
        long monthsBetween = ChronoUnit.MONTHS.between(start, end);
        System.out.println("Months between: " + monthsBetween);
    }
}

Output:

Days between: 365
Months between: 12
  • ChronoUnit.DAYS.between() এবং ChronoUnit.MONTHS.between() ব্যবহার করে দিন এবং মাসের মধ্যে পার্থক্য দ্রুত এবং কার্যকরীভাবে গণনা করা হয়েছে।

  1. Better Time Zone Management:
    • java.time API টাইমজোন পরিচালনায় খুবই শক্তিশালী, বিশেষ করে ZonedDateTime, ZoneId এবং OffsetDateTime এর মাধ্যমে। Java Time API তারিখ এবং সময়ের সাথে টাইমজোন সম্পর্কিত হিসাব দ্রুত এবং নির্ভুলভাবে করে থাকে। ZoneId ক্লাসটি গ্লোবাল টাইমজোনের জন্য একক মানক API প্রদান করে, যা performance বৃদ্ধি করে, কারণ এটি টাইমজোন সম্পর্কিত গণনা সহজ এবং দ্রুত করে তোলে।

Example: Working with Time Zones and ZonedDateTime:

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class TimeZoneExample {
    public static void main(String[] args) {
        // Get the current time in a specific timezone
        ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println("Current time in Tokyo: " + tokyoTime);
        
        // Get the current time in UTC
        ZonedDateTime utcTime = ZonedDateTime.now(ZoneId.of("UTC"));
        System.out.println("Current UTC time: " + utcTime);
    }
}

Output:

Current time in Tokyo: 2024-12-23T15:30:45+09:00[Asia/Tokyo]
Current UTC time: 2024-12-23T06:30:45Z[UTC]
  • এখানে ZonedDateTime.now(ZoneId.of("Asia/Tokyo")) এবং ZonedDateTime.now(ZoneId.of("UTC")) ব্যবহার করে দ্রুত টাইমজোন পরিবর্তন করা হয়েছে, এবং এটি পারফরম্যান্সে কোনো সমস্যা সৃষ্টি না করে সময় সঠিকভাবে প্রদর্শন করছে।

  1. Optimized DateTimeFormatter:
    • DateTimeFormatter ক্লাসটি তারিখ এবং সময়ের স্ট্রিংয়ের প্যার্সিং এবং ফরম্যাটিংয়ে ব্যবহৃত হয়। DateTimeFormatter ক্লাসে fast-path parsing অপটিমাইজেশন রয়েছে, যা স্ট্রিং প্যার্সিং ও ফরম্যাটিং দ্রুত করতে সহায়ক।

Java Time API এর Performance Optimization Techniques:

  1. Immutable Objects:
    • Immutable objects ব্যবহার করলে সিস্টেমের মেমরি ব্যবস্থাপনা এবং thread safety অনেক উন্নত হয়, যা পারফরম্যান্সে সাহায্য করে।
  2. ChronoUnit এবং Duration:
    • ChronoUnit এবং Duration ব্যবহার করে দ্রুত গণনা করা যায় এবং টাইম ক্যালকুলেশন দ্রুত ও নির্ভুল হয়।
  3. Efficient Time Zone Management:
    • ZoneId এবং ZonedDateTime এর মাধ্যমে টাইমজোন সম্পর্কিত কাজের জন্য একক API ব্যবহারের ফলে পারফরম্যান্স ভালো হয়।
  4. Reusing Formatters:
    • DateTimeFormatter-এর immutable প্রকৃতি এবং fast-path parsing দ্বারা ফরম্যাটিং এবং প্যার্সিং প্রক্রিয়ায় গতি বৃদ্ধি পায়।
  5. Avoiding Unnecessary Object Creation:
    • LocalDate, LocalTime বা ZonedDateTime তৈরি করার সময়, প্রক্রিয়াটির মধ্যে অপ্রয়োজনীয় অবজেক্ট তৈরি এড়ানো উচিত। ইমিউটেবল অবজেক্ট ব্যবহারে unnecessary memory allocation কম হয়।

  • java.time API তারিখ এবং সময়ের সাথে সম্পর্কিত কাজের জন্য পারফরম্যান্সে উন্নতি করতে অনেক কার্যকরী ফিচার প্রদান করে।
  • Immutable objects, optimized parsing, efficient time zone management, এবং chrono units ব্যবহার করে performance উন্নত করা যায়।
  • Java Time API ব্যবহার করে আপনি time calculations, date-time formatting, time zone adjustments, এবং DST handling-এর জন্য অত্যন্ত কার্যকরী এবং উচ্চ পারফরম্যান্স সমাধান পেতে পারেন।
Content added By

Immutable Objects এবং তাদের পারফরমেন্স

56
56

Immutable objects হল এমন অবজেক্ট যা তার তৈরি হওয়ার পর থেকে পরিবর্তন করা যায় না। একবার একটি অবজেক্ট তৈরি হলে তার অবস্থা অপরিবর্তনীয় (unchangeable) থাকে। Java Time API-এর অনেক ক্লাস, যেমন LocalDate, LocalDateTime, ZonedDateTime, Instant, ইত্যাদি, সবই immutable। এর মানে হলো, আপনি একবার একটি অবজেক্ট তৈরি করার পরে, তার অবস্থা বা মান পরিবর্তন করতে পারবেন না।

Immutable objects সম্পর্কে ধারণা এবং তাদের পারফরম্যান্সের সুবিধা সম্পর্কে এই পোস্টে আলোচনা করা হবে।


Immutable Objects in Java

Immutable objects সাধারণত thread-safe (থ্রেড সেফ) হয়ে থাকে, কারণ তাদের অবস্থা কখনো পরিবর্তিত হয় না। এই ধরনের অবজেক্টের মধ্যে state পরিবর্তন না হওয়ায় একাধিক থ্রেড একই অবজেক্টে কাজ করতে পারে এবং তাদের পারফরম্যান্সে কোনো নেতিবাচক প্রভাব পড়ে না।

Java Time API-তে Immutable Objects

Java Time API-তে LocalDate, LocalDateTime, Instant, ZonedDateTime, Duration, Period ইত্যাদি সবই immutable ক্লাস। এগুলোর মধ্যে একবার অবজেক্ট তৈরি করার পর তার মান পরিবর্তন করা সম্ভব নয়। উদাহরণস্বরূপ:

  • LocalDate: একটি তারিখ (দিন, মাস, বছর) প্রতিনিধিত্ব করে।
  • ZonedDateTime: একটি নির্দিষ্ট তারিখ এবং সময়, টাইমজোন সহ।
  • Instant: UTC-এ একটি নির্দিষ্ট মুহূর্ত।

এগুলোর প্রতিটি ক্লাসেই immutable ডিজাইন রয়েছে, যার ফলে আপনি নতুন মান তৈরি করতে পারলেও পুরনো অবজেক্ট পরিবর্তন করতে পারবেন না।


Immutable Objects এর সুবিধা

  1. Thread-Safety:
    • যেহেতু Immutable objects কখনো পরিবর্তিত হয় না, সুতরাং এগুলো thread-safe। একাধিক থ্রেড একসাথে কাজ করলেও কোনো ডেটা করাপশন বা সমস্যা হবে না। এটি multithreading এর ক্ষেত্রে খুবই কার্যকরী, কারণ এখানে কোন synchronization এর দরকার হয় না।
  2. Performance:
    • Immutable objects এর পরিবর্তনে কষ্ট কম থাকে, কারণ আপনি নতুন অবজেক্ট তৈরি করতে পারেন, কিন্তু পুরনো অবজেক্টের অবস্থা পরিবর্তন হয় না। এতে garbage collection এবং memory management ভালভাবে কাজ করে।
    • Reuse: Immutable objects এর ব্যবহারে বারবার একই অবজেক্ট ব্যবহার করা যায়, ফলে memory usage কম থাকে।
  3. Easier to Debug:
    • Immutable objects এ অবস্থা পরিবর্তন না হওয়ার কারণে এগুলি সহজে ডিবাগ করা যায়। যেমন, যখন কোনো অবজেক্টের অবস্থা পরিবর্তিত হয়, তখন আপনি জানেন না কীভাবে বা কোথায় সেটা পরিবর্তন হয়েছে, কিন্তু immutable objects এর ক্ষেত্রে এটা সমস্যা তৈরি করে না।
  4. Safe Sharing:
    • একাধিক থ্রেড বা ক্লাস যখন একই immutable object শেয়ার করে, তখন কোনো প্রতিকূল প্রভাব না পড়লে তাদের মধ্যে data race বা inconsistent state তৈরি হয় না। এটি safe sharing নিশ্চিত করে।

Java Time API Immutable Objects এর পারফরম্যান্স

Java Time API-তে immutable অবজেক্টের পারফরম্যান্স বেশ ভালো। তবে, এটি কিছু নির্দিষ্ট কেসে এক্সট্রা অবজেক্ট ক্রিয়েশন করতে পারে, যেমন আপনি যখন LocalDate বা LocalDateTime এ কোনো পরিবর্তন করতে চান, তখন একটি নতুন অবজেক্ট তৈরি হয়। এটি হয়তো memory allocation বাড়াতে পারে, তবে এর পারফরম্যান্স সাধারণত উন্নত, বিশেষত multi-threaded environments-এ।

Immutable Objects পারফরম্যান্সে প্রভাব

  1. Object Creation Overhead:
    • Immutable objects এর ক্ষেত্রে অবজেক্ট তৈরির জন্য কিছু অতিরিক্ত ওভারহেড হতে পারে, কারণ প্রতিটি পরিবর্তনের জন্য নতুন অবজেক্ট তৈরি করতে হয়। তবে, এই ওভারহেডটি সাধারণত নগণ্য এবং JVM (Java Virtual Machine) এর সাথে খুব ভালোভাবে অপটিমাইজ করা থাকে।
  2. Cacheability:
    • Immutable objects অনেক সময় ক্যাশিংয়ের জন্য উপযোগী হতে পারে, কারণ তাদের অবস্থা পরিবর্তিত না হওয়ার কারণে এগুলি পুনরায় ব্যবহার করা সহজ হয়। Java Time API তে LocalDateTime বা ZonedDateTime ইত্যাদি অ্যাবস্ট্রাক্ট টাইপগুলো বারবার একই মান ব্যবহার করতে সক্ষম।
  3. Optimized for Thread Safety:
    • Immutable objects নিজেই thread-safe হওয়ায় synchronization এর প্রয়োজন পড়ে না। একাধিক থ্রেড যখন একই অবজেক্টে কাজ করে, তখন ডেটা কোন্ফ্লিক্টের কোনো সম্ভাবনা থাকে না। এটি কার্যকরীভাবে CPU ব্যবহার এবং পারফরম্যান্স বৃদ্ধি করতে সহায়ক।

Immutable Objects: Example in Java Time API

LocalDate এবং ZonedDateTime এর উদাহরণ হিসেবে দেখা যাক কিভাবে immutable objects কাজ করে:

Example: LocalDate (Immutable)

import java.time.LocalDate;

public class ImmutableObjectExample {
    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2024, 12, 23);
        System.out.println("Original date: " + date1);
        
        // Modify the date by adding 5 days, which will return a new object
        LocalDate date2 = date1.plusDays(5);
        System.out.println("Modified date (after adding 5 days): " + date2);
        
        // Verify that original date remains unchanged
        System.out.println("Original date remains unchanged: " + date1);
    }
}

Output:

Original date: 2024-12-23
Modified date (after adding 5 days): 2024-12-28
Original date remains unchanged: 2024-12-23

ব্যাখ্যা:

  • এখানে, LocalDate একটি immutable অবজেক্ট। যখন date1.plusDays(5) মেথডটি কল করা হয়েছে, তখন একটি নতুন LocalDate অবজেক্ট তৈরি হয়েছে, কিন্তু date1 অপরিবর্তিত রয়েছে।

Example: ZonedDateTime (Immutable)

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class ImmutableZonedDateTimeExample {
    public static void main(String[] args) {
        ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("America/New_York"));
        System.out.println("Original ZonedDateTime: " + zonedDateTime1);

        // Modify the ZonedDateTime by adding 3 hours
        ZonedDateTime zonedDateTime2 = zonedDateTime1.plusHours(3);
        System.out.println("Modified ZonedDateTime (after adding 3 hours): " + zonedDateTime2);
        
        // Verify that original ZonedDateTime remains unchanged
        System.out.println("Original ZonedDateTime remains unchanged: " + zonedDateTime1);
    }
}

Output:

Original ZonedDateTime: 2024-12-23T10:30:15.123456-05:00[America/New_York]
Modified ZonedDateTime (after adding 3 hours): 2024-12-23T13:30:15.123456-05:00[America/New_York]
Original ZonedDateTime remains unchanged: 2024-12-23T10:30:15.123456-05:00[America/New_York]

ব্যাখ্যা:

  • ZonedDateTime একটি immutable অবজেক্ট। যখন আপনি plusHours() মেথড ব্যবহার করেন, এটি একটি নতুন ZonedDateTime অবজেক্ট তৈরি করে, এবং পুরনো অবজেক্ট অপরিবর্তিত থাকে।

  1. Immutable objects হল এমন অবজেক্ট যা তৈরি হওয়ার পর থেকে কোনো পরিবর্তন হয় না, এবং Java Time API-তে LocalDate, ZonedDateTime, Instant এবং অন্যান্য টাইম ক্লাসগুলি immutable
  2. Thread-safety এবং performance এর ক্ষেত্রে immutable objects অনেক সুবিধা প্রদান করে, যেমন no need for synchronization এবং safe sharing
  3. Immutable objects পারফরম্যান্সের উপর তেমন নেতিবাচক প্রভাব ফেলে না, কারণ Java Virtual Machine (JVM) এই ধরনের অবজেক্টগুলিকে অপটিমাইজ করে।
  4. Java Time API-তে immutable objects ব্যবহার করার ফলে কোড অনেক সঠিক, নিরাপদ এবং সহজে রক্ষণাবেক্ষণযোগ্য হয়।

Immutable objects ব্যবহারের মাধ্যমে সময় এবং তারিখ সম্পর্কিত কাজগুলো আরও কার্যকরী এবং সঠিকভাবে সম্পন্ন করা যায়।

Content added By

Parsing এবং Formatting এ Performance Optimization

138
138

Java 8-এ java.time প্যাকেজটি অন্তর্ভুক্ত হওয়ার পর, টাইম এবং তারিখের কাজগুলি অনেক সহজ এবং কার্যকরী হয়েছে। তবে, একে আরও দ্রুত এবং কার্যকরীভাবে ব্যবহারের জন্য parsing (স্ট্রিং থেকে LocalDate, ZonedDateTime, ইত্যাদি অবজেক্টে রূপান্তর) এবং formatting (টাইম অবজেক্ট থেকে স্ট্রিং তৈরি) করার সময় পারফরম্যান্স অপটিমাইজেশন করা অত্যন্ত গুরুত্বপূর্ণ।

Parsing এবং Formatting:

  1. Parsing: একটি স্ট্রিং থেকে তারিখ বা সময়ের অবজেক্ট তৈরি করার প্রক্রিয়া। যেমন, একটি তারিখের স্ট্রিং যেমন "2024-12-23" থেকে একটি LocalDate অবজেক্ট তৈরি করা।
  2. Formatting: একটি তারিখ বা সময় অবজেক্ট (যেমন LocalDate, LocalTime, ZonedDateTime) কে একটি স্ট্রিং ফরম্যাটে রূপান্তর করার প্রক্রিয়া। যেমন, LocalDate অবজেক্টকে "2024-12-23" স্ট্রিংয়ে রূপান্তর করা।

Performance Optimization Strategies for Parsing and Formatting in Java Time API

  1. Use Predefined Formatters:
    • Java Time API DateTimeFormatter ক্লাসে কিছু প্রি-ডিফাইন্ড (pre-defined) ফরম্যাটার রয়েছে, যেমন DateTimeFormatter.ISO_LOCAL_DATE। এই প্রি-ডিফাইন্ড ফরম্যাটারগুলি ব্যবহার করার মাধ্যমে আপনি ফরম্যাটিং এবং প্যার্সিং করতে পারবেন দ্রুত এবং দক্ষভাবে, কারণ এগুলি immutable এবং তাদের মধ্যে কোনো পুনরায় গণনা বা কম্পাইল করার প্রয়োজন নেই।
  2. Avoid Repeated Formatter Creation:
    • যখন আপনি একটি নির্দিষ্ট ফরম্যাটের জন্য প্যার্সিং বা ফরম্যাটিং বারবার করছেন, তখন DateTimeFormatter অবজেক্টটি বারবার তৈরি না করে, একটি static final ফরম্যাটার তৈরি করুন এবং সেটি পুনরায় ব্যবহার করুন। এটি পারফরম্যান্সে সহায়তা করবে।
  3. Use DateTimeFormatter with parse and format Methods Efficiently:
    • DateTimeFormatter এর parse() এবং format() মেথডগুলি Thread-safe কিন্তু পুনরায় immutable নয়। তাই, যদি একই ফরম্যাট ব্যবহার করে বারবার প্যার্সিং বা ফরম্যাটিং করা হয়, তবে পুনরায় ফরম্যাটার তৈরি করার পরিবর্তে একই DateTimeFormatter অবজেক্ট ব্যবহার করুন।

Optimizing Parsing and Formatting with DateTimeFormatter

1. Use Predefined DateTimeFormatter for Common Formats

DateTimeFormatter.ISO_LOCAL_DATE, DateTimeFormatter.ISO_LOCAL_TIME, DateTimeFormatter.ISO_LOCAL_DATE_TIME ইত্যাদি প্রি-ডিফাইন্ড ফরম্যাটার ব্যবহার করে প্যার্সিং এবং ফরম্যাটিং করলে পারফরম্যান্স উন্নত হয়।

Example: Using Predefined Formatter
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class PredefinedFormatterExample {
    public static void main(String[] args) {
        // Use predefined formatter for ISO date format
        String dateStr = "2024-12-23";
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;

        // Parse the date string
        LocalDate date = LocalDate.parse(dateStr, formatter);
        System.out.println("Parsed Date: " + date);

        // Format the LocalDate object
        String formattedDate = date.format(formatter);
        System.out.println("Formatted Date: " + formattedDate);
    }
}

Output:

Parsed Date: 2024-12-23
Formatted Date: 2024-12-23

ব্যাখ্যা:

  • DateTimeFormatter.ISO_LOCAL_DATE একটি প্রি-ডিফাইন্ড ফরম্যাটার যা দ্রুত এবং কার্যকরীভাবে প্যার্সিং এবং ফরম্যাটিং করার জন্য ব্যবহৃত হয়।

2. Avoid Creating New Formatters for Each Operation

একটি DateTimeFormatter অবজেক্ট বারবার তৈরি করার পরিবর্তে, এটি একটি static final ফিল্ড হিসেবে তৈরি করুন, যাতে একবার তৈরি হওয়া formatter পুনরায় ব্যবহার করা যায়।

Example: Reusing DateTimeFormatter for Multiple Operations
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class ReusingFormatterExample {
    // Reuse the formatter
    private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;

    public static void main(String[] args) {
        String dateStr1 = "2024-12-23";
        String dateStr2 = "2025-01-01";

        // Reusing the formatter for multiple operations
        LocalDate date1 = LocalDate.parse(dateStr1, formatter);
        LocalDate date2 = LocalDate.parse(dateStr2, formatter);

        System.out.println("Parsed Date 1: " + date1);
        System.out.println("Parsed Date 2: " + date2);

        // Formatting the dates
        String formattedDate1 = date1.format(formatter);
        String formattedDate2 = date2.format(formatter);

        System.out.println("Formatted Date 1: " + formattedDate1);
        System.out.println("Formatted Date 2: " + formattedDate2);
    }
}

Output:

Parsed Date 1: 2024-12-23
Parsed Date 2: 2025-01-01
Formatted Date 1: 2024-12-23
Formatted Date 2: 2025-01-01

ব্যাখ্যা:

  • DateTimeFormatter অবজেক্টটি static final ফিল্ড হিসেবে পুনরায় ব্যবহৃত হয়েছে, ফলে প্রতি প্যার্সিং বা ফরম্যাটিং অপারেশন এ নতুন DateTimeFormatter অবজেক্ট তৈরি করা হয়নি, যা পারফরম্যান্স উন্নত করেছে।

3. Use DateTimeFormatterBuilder for Custom Formats

যদি আপনাকে একটি কাস্টম date/time ফরম্যাট তৈরি করতে হয়, তাহলে DateTimeFormatterBuilder ব্যবহার করুন। এটি একাধিক ফরম্যাটারকে একত্রিত করার জন্য এবং নির্দিষ্ট format pattern তৈরি করার জন্য উপকারী।

Example: Using DateTimeFormatterBuilder
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class CustomFormatterExample {
    public static void main(String[] args) {
        // Use DateTimeFormatterBuilder to create a custom format
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.YEAR, 4) // Year with 4 digits
            .appendLiteral("-")  // Add hyphen separator
            .appendValue(ChronoField.MONTH_OF_YEAR, 2) // Month with 2 digits
            .appendLiteral("-")
            .appendValue(ChronoField.DAY_OF_MONTH, 2) // Day with 2 digits
            .toFormatter();

        String dateStr = "2024-12-23";
        LocalDate date = LocalDate.parse(dateStr, formatter);

        System.out.println("Parsed Date: " + date);
    }
}

Output:

Parsed Date: 2024-12-23

ব্যাখ্যা:

  • DateTimeFormatterBuilder ব্যবহার করে একটি কাস্টম ফরম্যাট তৈরি করা হয়েছে, যা year-month-day ফরম্যাটে স্ট্রিং প্যার্স করে।

4. Format Only When Necessary

ফরম্যাটিং অপারেশন কেবল তখন করুন যখন এটি বাস্তবিক প্রয়োজন হয়, কারণ ফরম্যাটিং প্রক্রিয়া সঠিক সময়ে অপ্রয়োজনীয় হতে পারে এবং পারফরম্যান্স কমাতে পারে।

  1. Predefined Formatters: ব্যবহার করা DateTimeFormatter এর জন্য প্রস্তুত থাকা ফরম্যাটারগুলি, যেমন DateTimeFormatter.ISO_LOCAL_DATE, দ্রুত এবং কার্যকরী পারফরম্যান্স দেয়।
  2. Avoid Repeated Formatter Creation: প্রতিবার নতুন DateTimeFormatter অবজেক্ট তৈরি না করে, একটি স্থির বা স্ট্যাটিক ফরম্যাটার ব্যবহার করুন।
  3. Use DateTimeFormatterBuilder: কাস্টম ফরম্যাটে ফরম্যাটার তৈরি করার জন্য DateTimeFormatterBuilder ব্যবহার করুন।
  4. Format Only When Necessary: স্ট্রিং ফরম্যাটিং অপারেশন শুধুমাত্র তখনই করুন যখন তা সত্যিকারভাবে প্রয়োজন।

এই কৌশলগুলি অনুসরণ করলে আপনি parsing এবং formatting অপারেশনগুলিতে পারফরম্যান্স অপটিমাইজেশন করতে সক্ষম হবেন।

Content added By

উদাহরণ সহ Performance Optimization Techniques

100
100

Java 8-এর java.time প্যাকেজটি তারিখ এবং সময়ের সাথে কাজ করার জন্য উন্নত, নির্ভুল এবং সহজ টুল প্রদান করে। যদিও এটি অনেক সুবিধা প্রদান করে, তবে কিছু ক্ষেত্রে পারফরম্যান্স অপটিমাইজেশন প্রয়োজন হতে পারে, বিশেষ করে বড় ডেটা বা ইনপুটের সাথে কাজ করার সময়।

এই পোস্টে আমরা Java Time API ব্যবহার করার সময় কিছু পারফরম্যান্স অপটিমাইজেশন টেকনিক্স দেখব এবং উদাহরণের মাধ্যমে সেগুলি বুঝে দেখব।

1. Avoiding Unnecessary Object Creation

একটি সাধারণ পারফরম্যান্স অপটিমাইজেশন কৌশল হল অপ্রয়োজনীয় অবজেক্ট ক্রিয়েশন এড়ানো। java.time প্যাকেজে কিছু immutable objects যেমন LocalDate, LocalDateTime, ZonedDateTime, Instant ক্লাসগুলির সঙ্গে কাজ করার সময় অবজেক্ট ক্রিয়েশন কমানো উচিত।

Example:

import java.time.LocalDateTime;

public class PerformanceOptimizationExample {
    public static void main(String[] args) {
        // Avoid creating a new LocalDateTime object every time
        LocalDateTime now = LocalDateTime.now();
        
        // Reuse the same LocalDateTime object
        for (int i = 0; i < 1000000; i++) {
            LocalDateTime reusedTime = now.plusMinutes(i); // Reusing the same base object
        }
        
        System.out.println("Optimization applied - Reused the same object");
    }
}

Explanation:

  • এখানে, আমরা LocalDateTime.now() একবার ক্রিয়েট করে পরবর্তীতে তার সাথে plusMinutes(i) মেথড ব্যবহার করে সময় পরিবর্তন করছি, যা অপ্রয়োজনীয় অবজেক্ট ক্রিয়েশন থেকে বাঁচায়।

2. Using Instant for High-Precision Time Measurements

Instant ক্লাসটি high precision time মাপার জন্য উপযুক্ত। যদি আপনার সিস্টেম টাইমের উপর নির্ভরশীল কিছু performance measurements করতে হয়, তবে Instant ব্যবহার করা উচিত। Instant.now() এবং Instant.now().toEpochMilli() সময়ের খুব সঠিক মান প্রদান করতে সক্ষম।

Example:

import java.time.Instant;

public class InstantPerformanceMeasurementExample {
    public static void main(String[] args) {
        Instant start = Instant.now(); // Start the timer

        // Simulate a task
        for (int i = 0; i < 1000000; i++) {
            Math.pow(i, 2);
        }

        Instant end = Instant.now(); // End the timer
        long duration = end.toEpochMilli() - start.toEpochMilli(); // Duration in milliseconds
        System.out.println("Task duration: " + duration + " milliseconds");
    }
}

Explanation:

  • Instant.now() ব্যবহার করে সঠিক সময় মাপা হয়েছে এবং এরপর দুইটি Instant অবজেক্টের মধ্যে পার্থক্য বের করা হয়েছে। এটি টাইম পরিমাপের জন্য দ্রুত এবং নির্ভুল পদ্ধতি।

3. Avoiding Repeated DateTimeFormatter Creation

DateTimeFormatter একটি immutable object যা তারিখ এবং সময় স্ট্রিং পার্স করার জন্য ব্যবহৃত হয়। তবে, এটি যদি বারবার ক্রিয়েট করা হয়, তবে পারফরম্যান্সে নেতিবাচক প্রভাব ফেলতে পারে। অতএব, একে reuse করা উচিত।

Example:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTimeFormatterOptimizationExample {
    public static void main(String[] args) {
        // Define formatter once
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // Reuse formatter for formatting date-time multiple times
        for (int i = 0; i < 1000000; i++) {
            String formattedDate = LocalDateTime.now().format(formatter); // Reuse the formatter
        }

        System.out.println("DateTimeFormatter reused for performance optimization");
    }
}

Explanation:

  • এখানে, আমরা DateTimeFormatter একবার তৈরি করে বারবার ব্যবহার করেছি, যা পারফরম্যান্স অপটিমাইজেশন হিসেবে কাজ করেছে। প্রতিবার নতুন একটি DateTimeFormatter তৈরি না করে, শুধুমাত্র একটিকে পুনরায় ব্যবহার করা হয়েছে।

4. Efficient Use of ZonedDateTime for Time Zone Conversion

ZonedDateTime টাইমজোন সম্পর্কিত পরিবর্তনের জন্য ব্যবহার করা হয়। কিন্তু টাইমজোন কনভার্সন অনেক সময় কম্পিউটেশনালভাবে ব্যয়বহুল হতে পারে। তাই টাইমজোন কনভার্সন যখন প্রয়োজন, তখন তাকে যতটুকু সম্ভব মিনি-াইজ করা উচিত।

Example:

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class ZonedDateTimeOptimizationExample {
    public static void main(String[] args) {
        // Get current time in UTC
        ZonedDateTime utcTime = ZonedDateTime.now(ZoneId.of("UTC"));

        // Reuse the ZonedDateTime for multiple conversions
        for (int i = 0; i < 1000000; i++) {
            ZonedDateTime kolkataTime = utcTime.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
        }

        System.out.println("Efficient ZonedDateTime conversion");
    }
}

Explanation:

  • withZoneSameInstant() মেথডটি টাইমজোনের মধ্যে পরিবর্তন ঘটায়, কিন্তু সময়টি অপরিবর্তিত রাখে। এখানে টাইমজোন কনভার্সন একবার করে পুনরায় ব্যবহার করা হয়েছে, যা সময় অপচয় কমিয়ে পারফরম্যান্সে সহায়ক।

5. Using Duration and Period for Date/Time Calculations

Duration এবং Period ক্লাসগুলি সময় সম্পর্কিত গণনার জন্য ব্যবহৃত হয়। তবে, এই ক্লাসগুলি ব্যবহার করার সময় গণনা করলে নির্দিষ্ট টাইম ইউনিট (যেমন সেকেন্ড, মিনিট, দিন ইত্যাদি) ব্যবহার করা গুরুত্বপূর্ণ, যাতে unnecessary সেকেন্ড পারফরম্যান্স ব্যয় থেকে বাঁচা যায়।

Duration Example:

import java.time.Duration;
import java.time.Instant;

public class DurationPerformanceExample {
    public static void main(String[] args) {
        Instant start = Instant.now();

        // Simulate a task
        for (int i = 0; i < 1000000; i++) {
            Math.pow(i, 2);
        }

        Instant end = Instant.now();

        // Use Duration to calculate the difference
        Duration duration = Duration.between(start, end);
        System.out.println("Task duration in seconds: " + duration.getSeconds());
    }
}

Explanation:

  • Duration.between() ব্যবহার করে সঠিক সময় পার্থক্য বের করা হয়েছে এবং getSeconds() দিয়ে সেকেন্ড হিসেবে ফলাফল পাওয়া গেছে। এটি কম সময় এবং সঠিকভাবে হিসাব করতে সাহায্য করে।

6. Avoiding LocalDateTime.now() for High-Precision Tasks

যখন আপনি খুব নির্ভুল সময় পরিমাপ করতে চান (যেমন high-frequency tasks), তখন LocalDateTime.now() ব্যবহার করা এড়ানো উচিত, কারণ এটি কমপক্ষে মিলিসেকেন্ড (বা এর থেকে কম) পর্যন্ত নির্ভুল। এর পরিবর্তে Instant.now() ব্যবহার করা উচিত, যা সেকেন্ড এবং ন্যানোসেকেন্ডে উচ্চতর সঠিকতা প্রদান করে।

Example:

import java.time.Instant;

public class HighPrecisionTimeMeasurementExample {
    public static void main(String[] args) {
        Instant start = Instant.now();

        // Simulate a task with high precision timing
        for (int i = 0; i < 1000000; i++) {
            Math.pow(i, 2);
        }

        Instant end = Instant.now();
        long duration = end.toEpochMilli() - start.toEpochMilli(); // Duration in milliseconds
        System.out.println("Task duration: " + duration + " milliseconds");
    }
}

Explanation:

  • Instant.now() উচ্চ সঠিকতায় টাইম পরিমাপ করতে সহায়ক। এটি nanosecond পর্যন্ত নির্ভুল সময় প্রদান করে, যা LocalDateTime থেকে আরও বেশি পারফরম্যান্স দেয়।

  1. Avoid Unnecessary Object Creation: Java Time API-তে DateTimeFormatter এবং ZonedDateTime এর মতো অবজেক্টের পুনরায় ব্যবহার করা উচিত।
  2. Use Instant for High Precision: Instant.now() টাইম পরিমাপের জন্য উচ্চ সঠিকতা প্রদান করে।
  3. Efficient Time Zone Conversion: ZonedDateTime এবং withZoneSameInstant() এর মাধ্যমে টাইমজোন কনভার্সন সহজ এবং কার্যকরী করা যায়।
  4. Use Duration and Period Efficiently: সময়ের পার্থক্য নির্ধারণ করার সময়, Duration এবং Period শ্রেণী ব্যবহার করা বেশি কার্যকরী এবং সঠিক।
  5. Avoid LocalDateTime.now() for High Precision: উচ্চ সঠিকতার জন্য Instant.now() ব্যবহার করা উচিৎ।

এই পারফরম্যান্স অপটিমাইজেশন কৌশলগুলো Java Time API এর কার্যকারিতা এবং নির্ভুলতার সঙ্গে আপনার কোডের পারফরম্যান্স উন্নত করতে সহায়ক।

Content added By
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion