0Pricing
Java Academy · درس

كتابة اختبار أداء

@Benchmark والأنماط

كتابة اختبار أداء درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

كتابة اختبار معياري

اختبار JMH المعياري ليس سوى دالة عليها التعليق التوضيحي @Benchmark داخل فئة عادية. ينشئ معالج التعليقات التوضيحية في JMH إطار الاختبار المحيط بها. يغطي هذا الدرس التعليقات التوضيحية التي تحدّد ما الذي تقيسونه وكيفية قياسه.

التعليق التوضيحي @Benchmark

ضعوا التعليق التوضيحي @Benchmark على أي دالة عامة، وسيستدعيها JMH مرارًا ويقيس زمن كل استدعاء. ينبغي إعادة قيمة الدالة، لا تجاهلها، حتى يتمكن JMH من استهلاكها.

فئة اختبار معيارية بسيطة

إليكم الهيكل الأساسي لاختبار معياري. الاستيراد هو org.openjdk.jmh.annotations.*. وبما أن JMH غير موجود في مسار الفئات الخاص ببيئة التشغيل هذه، فهذا المثال توضيحي فقط.

import org.openjdk.jmh.annotations.Benchmark;

public class StringBench {
    @Benchmark
    public String concat() {
        return "foo" + System.nanoTime();
    }
}

أوضاع الاختبار المعياري

يحدّد @BenchmarkMode ما يتم الإبلاغ عنه:

  • Throughput — عدد العمليات لكل وحدة زمنية (الأعلى أفضل).
  • AverageTime — الزمن لكل عملية (الأقل أفضل).
  • SampleTime — توزيع الأزمنة (النسب المئوية).
  • SingleShotTime — استدعاء واحد، وهو مناسب لقياس بدء التشغيل البارد.
import org.openjdk.jmh.annotations.*;

public class Bench {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    public int work() {
        return 2 + 2;
    }
}

اختيار وحدات الإخراج

يحدّد @OutputTimeUnit وحدة الزمن في التقرير لتكون الأرقام واضحة. وتناسب النانوثواني العملية السريعة، بينما تناسب الميليثواني العملية البطيئة.

import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;

public class Bench {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int work() {
        return 42;
    }
}

إعادة النتائج

أعيدوا دائمًا نتيجة العمل. يمرّر JMH القيم المُعادة إلى Blackhole تلقائيًا، مما يمنع إزالة الشيفرة الميتة. ومن الأخطاء الشائعة إنشاء اختبار معياري من نوع void يحسب قيمة ثم يتجاهلها.

الإعدادات الافتراضية للتعليقات التوضيحية

يمكن وضع التعليقات التوضيحية على الدالة أو على الفئة بأكملها. وتنطبق التعليقات التوضيحية الموضوعة على مستوى الفئة على كل @Benchmark في تلك الفئة، مما يحافظ على مبدأ عدم تكرار الإعدادات عند وجود عدة اختبارات معيارية مترابطة.

التشغيل المنفصل

يشغّل @Fork(n) الاختبار المعياري في عدد n من عمليات JVM الجديدة. ويعزل التشغيل المنفصل كل عملية تشغيل عن ملفات تعريف JIT التي أنشأتها الاختبارات المعيارية السابقة، مما يحسّن قابلية إعادة إنتاج النتائج. والقيمة الافتراضية هي عملية تشغيل منفصلة واحدة.

import org.openjdk.jmh.annotations.*;

@Fork(2)
public class Bench {
    @Benchmark
    public long now() {
        return System.nanoTime();
    }
}

تشغيل Runner

تبدؤون الاختبارات المعيارية عبر main يضبط كائن Options وكائن Runner، أو عبر ملف JAR القابل للتنفيذ الذي جرى إنشاؤه. ويحدّد التعبير النمطي include(...) الاختبارات المعيارية التي سيتم تشغيلها.

import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.*;

public class Launcher {
    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
            .include("Bench")
            .build();
        new Runner(opt).run();
    }
}

قراءة النتائج

يطبع JMH جدولًا يتضمن اسم الاختبار المعياري والوضع وعدد العينات والنتيجة وخطأ النتيجة والوحدات، مثل: Bench.work avgt 25 3.142 +/- 0.011 ns/op. وتمثّل +/- فاصل الثقة.

حافظوا على تركيز الاختبارات المعيارية

ينبغي أن يقيس كل اختبار معياري أمرًا واحدًا. فخلط الإعداد والإدخال والإخراج والعملية قيد الاختبار يجعل النتيجة غير واضحة. انقلوا التحضير إلى دوال @Setup (وهو ما يُشرح مع الحالة) حتى لا يُقاس زمنيًا سوى المسار الساخن.

تحقق سريع

تحقّقوا من فهمكم لكيفية كتابة الاختبارات المعيارية.

مراجعة

تعلّمتم كيفية كتابة اختبار معياري باستخدام JMH:

  • ضعوا التعليق التوضيحي @Benchmark على دالة وأعيدوا النتيجة.
  • يختار @BenchmarkMode الوضع Throughput أو AverageTime أو SampleTime أو SingleShotTime.
  • يحدّد @OutputTimeUnit وحدات واضحة، ويعزل @Fork عمليات التشغيل في JVMs جديدة.
  • شغّلوا الاختبار باستخدام Runner مع Options أو باستخدام ملف JAR الذي جرى إنشاؤه.
  • حافظوا على تركيز كل اختبار معياري على مسار ساخن واحد.

الأسئلة الشائعة

هل درس «كتابة اختبار أداء» مجاني؟

نعم — نص درس «كتابة اختبار أداء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «كتابة اختبار أداء»؟

@Benchmark والأنماط تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «كتابة اختبار أداء»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا JMH
  2. كتابة اختبار أداء
  3. الإحماء والتكرارات
  4. تجنب حذف الشيفرة غير المستخدمة
← العودة إلى Java Academy