{fmt} هي مكتبة تنسيق مفتوحة المصدر توفر بديلاً سريعًا وآمنًا لتدفقات C stdio وC++ iostream.
إذا أعجبك هذا المشروع، يرجى التفكير في التبرع لأحد الصناديق التي تساعد ضحايا الحرب في أوكرانيا: https://www.stopputin.net/.
التوثيق
أوراق الغش
أسئلة وأجوبة: اطرح أسئلة على StackOverflow باستخدام العلامة fmt.
جرب {fmt} في Compiler Explorer.
واجهة برمجة تطبيقات ذات تنسيق بسيط مع وسائط موضعية للترجمة
تنفيذ C++ 20 std::format وC++23 std::print
تنسيق جملة السلسلة بشكل مشابه لتنسيق Python
منسق الفاصلة العائمة IEEE 754 سريع مع ضمانات التقريب والإختصار الصحيحة ذهابًا وإيابًا باستخدام خوارزمية Dragonbox
دعم يونيكود المحمولة
تنفيذ printf الآمن بما في ذلك امتداد POSIX للوسائط الموضعية
القابلية للتوسعة: دعم الأنواع المحددة من قبل المستخدم
أداء عالي: أسرع من تطبيقات المكتبات القياسية الشائعة لـ (s)printf
وiostreams و to_string
و to_chars
، راجع اختبارات السرعة وتحويل مائة مليون عدد صحيح إلى سلاسل في الثانية
حجم الكود صغير من حيث الكود المصدري مع الحد الأدنى من التكوين الذي يتكون من ثلاثة ملفات فقط، core.h
و format.h
و format-inl.h
والتعليمات البرمجية المجمعة؛ راجع ترجمة الوقت وتضخم التعليمات البرمجية
الموثوقية: تحتوي المكتبة على مجموعة واسعة من الاختبارات ويتم فحصها بشكل مستمر
السلامة: المكتبة آمنة تمامًا من حيث النوع، ويمكن الإبلاغ عن الأخطاء في سلاسل التنسيق في وقت الترجمة، وتمنع الإدارة التلقائية للذاكرة أخطاء تجاوز سعة المخزن المؤقت
سهولة الاستخدام: قاعدة تعليمات برمجية صغيرة قائمة بذاتها، لا توجد تبعيات خارجية، ترخيص MIT متساهل
إمكانية النقل مع إخراج متسق عبر الأنظمة الأساسية ودعم المترجمين الأقدم
قاعدة بيانات نظيفة خالية من التحذيرات حتى في مستويات التحذير العالية مثل -Wall -Wextra -pedantic
استقلال اللغة بشكل افتراضي
تم تمكين التكوين الاختياري للرأس فقط باستخدام الماكرو FMT_HEADER_ONLY
راجع الوثائق لمزيد من التفاصيل.
الطباعة إلى stdout (تشغيل)
#include <fmt/core.h>int main() { fmt::print("Hello,world!n"); }
تنسيق سلسلة (تشغيل)
std::string s = fmt::format("الإجابة هي {}.", 42);// s == "الإجابة هي 42."
تنسيق سلسلة باستخدام الوسائط الموضعية (تشغيل)
std::string s = fmt::format("أفضل أن أكون {1} بدلاً من {0}.", "right", "happy");// s == "أفضل أن أكون سعيدًا على أن أكون على حق" ".
طباعة التواريخ والأوقات (تشغيل)
#include <fmt/chrono.h>int main() { auto now = std::chrono::system_clock::now(); fmt::print("التاريخ والوقت: {}n"، الآن)؛ fmt::print("الوقت: {:%H:%M}n", now); }
الإخراج:
Date and time: 2023-12-26 19:10:31.557195597 Time: 19:10
طباعة حاوية (تشغيل)
#تتضمن <vector>#تتضمن <fmt/ranges.h>int main() { std::vector<int> v = {1, 2, 3}; fmt::print("{}n"، v); }
الإخراج:
[1, 2, 3]
التحقق من سلسلة التنسيق في وقت الترجمة
std::string s = fmt::format("{:d}", "أنا لست رقمًا");
وهذا يعطي خطأ في وقت الترجمة في C++ 20 لأن d
هو محدد تنسيق غير صالح لسلسلة.
كتابة ملف من موضوع واحد
#include <fmt/os.h>int main() { auto out = fmt::output_file("guide.txt"); out.print ("لا {}"، "الذعر")؛ }
يمكن أن يكون هذا أسرع من 5 إلى 9 مرات من fprintf.
الطباعة باستخدام الألوان وأنماط النص
#include <fmt/color.h>int main() { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "Hello, {}!n", "world" ); fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | fmt::emphasis::underline, "Olá, {}!n", "Mundo"); fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, "你好{}!n", "世界"); }
الإخراج على محطة حديثة مع دعم Unicode:
مكتبة | طريقة | وقت التشغيل، س |
---|---|---|
libc | printf | 0.91 |
libc++ | الأمراض المنقولة جنسيا::ostream | 2.49 |
{فمت} 9.1 | فمت::طباعة | 0.74 |
تنسيق التعزيز 1.80 | دفعة::تنسيق | 6.26 |
تنسيق حماقة | حماقة :: الشكل | 1.87 |
{fmt} هي أسرع الطرق المقيسة، أسرع بنسبة 20% تقريبًا من printf
.
تم إنشاء النتائج المذكورة أعلاه من خلال إنشاء tinyformat_test.cpp
على نظام التشغيل macOS 12.6.1 مع clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT
، والحصول على أفضل ثلاث عمليات تشغيل. في الاختبار، تتم تعبئة سلسلة التنسيق "%0.10f:%04d:%+g:%s:%p:%c:%%n"
أو ما يعادلها 2,000,000 مرة مع إرسال الإخراج إلى /dev/null
؛ لمزيد من التفاصيل الرجوع إلى المصدر.
{fmt} أسرع بما يصل إلى 20-30 مرة من std::ostringstream
و sprintf
على IEEE754 float
والتنسيق double
(dtoa-benchmark) وأسرع من التحويل المزدوج وryu:
يقوم البرنامج النصي bloat-test.py من اختبارات قياس التنسيق بتجميع الوقت وتضخم التعليمات البرمجية للمشاريع غير التافهة. يقوم بإنشاء 100 وحدة ترجمة ويستخدم printf()
أو بديله خمس مرات في كل منها لمحاكاة مشروع متوسط الحجم. يظهر الحجم القابل للتنفيذ الناتج ووقت الترجمة (إصدار Apple clang 15.0.0 (clang-1500.1.0.2.5)، وmacOS Sonoma، الأفضل من بين ثلاثة) في الجداول التالية.
البناء الأمثل (-O3)
طريقة | تجميع الوقت، ق | الحجم القابل للتنفيذ، KiB | الحجم المقطوع، KiB |
---|---|---|---|
printf | 1.6 | 54 | 50 |
IOStreams | 25.9 | 98 | 84 |
اف ام تي 83652df | 4.8 | 54 | 50 |
com.tinyformat | 29.1 | 161 | 136 |
تنسيق التعزيز | 55.0 | 530 | 317 |
{fmt} سريع التجميع ويمكن مقارنته بـ printf
من حيث الحجم الثنائي لكل مكالمة (ضمن خطأ تقريب في هذا النظام).
البناء غير الأمثل
طريقة | تجميع الوقت، ق | الحجم القابل للتنفيذ، KiB | الحجم المقطوع، KiB |
---|---|---|---|
printf | 1.4 | 54 | 50 |
IOStreams | 23.4 | 92 | 68 |
{فمت} 83652df | 4.4 | 89 | 85 |
com.tinyformat | 24.5 | 204 | 161 |
تنسيق التعزيز | 36.4 | 831 | 462 |
يتم ربط كل libc
و lib(std)c++
و libfmt
كمكتبات مشتركة لمقارنة حمل وظيفة التنسيق فقط. Boost Format عبارة عن مكتبة للترويسة فقط، لذا فهي لا توفر أي خيارات ربط.
برجاء الرجوع إلى بناء المكتبة للحصول على إرشادات حول كيفية إنشاء المكتبة وإجراء اختبارات الوحدة.
توجد المعايير في مستودع منفصل، معايير التنسيق، لذا لتشغيل المعايير، تحتاج أولاً إلى استنساخ هذا المستودع وإنشاء ملفات Makefiles باستخدام CMake:
$ git clone --recursive https://github.com/fmtlib/format-benchmark.git $ cd format-benchmark $ cmake .
وبعد ذلك يمكنك إجراء اختبار السرعة:
$ make speed-test
أو اختبار الانتفاخ:
$ make bloat-test
يوفر clang-tidy v18 فحص الاستخدام الحديث std-print القادر على تحويل تكرارات printf
و fprintf
إلى fmt::print
إذا تم تكوينها للقيام بذلك. (بشكل افتراضي يتم تحويله إلى std::print
.)
0 م: لعبة استراتيجية مجانية ومفتوحة المصدر ومتعددة المنصات
AMPL/MP: مكتبة مفتوحة المصدر للبرمجة الرياضية
Apple's FoundationDB: متجر مفتوح المصدر وموزع وذو قيمة أساسية للمعاملات
Aseprite: محرر الصور المتحركة وأداة رسم البكسل
AvioBook: مجموعة عمليات الطائرات الشاملة
Blizzard Battle.net: منصة ألعاب عبر الإنترنت
سيليستيا: تصور ثلاثي الأبعاد للفضاء في الوقت الحقيقي
Ceph: نظام تخزين موزع قابل للتطوير
ccache: ذاكرة التخزين المؤقت للمترجم
ClickHouse: نظام إدارة قواعد البيانات التحليلية
contextVision: برنامج التصوير الطبي
كفاف: محاكي طرفي حديث
CUAUV: مركبة تحت الماء مستقلة تابعة لجامعة كورنيل
دريك: مجموعة أدوات التخطيط والتحكم والتحليل للأنظمة الديناميكية غير الخطية (MIT)
المبعوث: وكيل C++ L7 وحافلة الاتصالات (Lyft)
FiveM: إطار تعديل لـ GTA V
fmtlog: مكتبة تسجيل عالية الأداء بنمط fmtlib مع زمن وصول بالنانو ثانية
الحماقة: مكتبة فيسبوك مفتوحة المصدر
GemRB: تطبيق محمول مفتوح المصدر لمحرك Bioware's Infinity Engine
Grand Mountain Adventure: لعبة تزلج وتزلج على الجليد في عالم مفتوح جميل
HarpyWar/pvpgn: شبكة ألعاب اللاعب مقابل اللاعب مع التعديلات
KBEngine: محرك خادم MMOG مفتوح المصدر
Keypirinha: مشغل دلالي لنظام التشغيل Windows
Kodi (xbmc سابقًا): برنامج المسرح المنزلي
Knuth: عقدة بيتكوين كاملة عالية الأداء
libunicode: مكتبة Unicode C++17 حديثة
MariaDB: نظام إدارة قواعد البيانات العلائقية
مايكروسوفت فيرونا: لغة برمجة بحثية للملكية المتزامنة
MongoDB: قاعدة بيانات المستندات الموزعة
MongoDB Smasher: أداة صغيرة لإنشاء مجموعات بيانات عشوائية
OpenSpace: إطار عمل للتصور الفلكي مفتوح المصدر
PenUltima Online (POL): خادم MMO، متوافق مع معظم عملاء Ultima Online
PyTorch: مكتبة مفتوحة المصدر للتعلم الآلي
quasardb: قاعدة بيانات ترابطية موزعة وعالية الأداء
Quill: مكتبة تسجيل غير متزامنة ذات زمن انتقال منخفض
QKW: تعميم الأسماء المستعارة لتبسيط التنقل وتنفيذ تسلسلات أوامر طرفية معقدة متعددة الأسطر
redis-cerberus: وكيل مجموعة Redis
redpanda: بديل Kafka® أسرع بـ 10 مرات للأنظمة ذات المهام الحرجة المكتوبة بلغة C++
rpclib: خادم C++ msgpack-RPC حديث ومكتبة عميل
Salesforce Analytics Cloud: برنامج ذكاء الأعمال
Scylla: مخزن بيانات NoSQL متوافق مع Cassandra يمكنه التعامل مع مليون معاملة في الثانية على خادم واحد
Seastar: إطار عمل C++ متقدم ومفتوح المصدر لتطبيقات الخادم عالية الأداء على الأجهزة الحديثة
spdlog: مكتبة تسجيل C++ فائقة السرعة
ستيلر: منصة مالية
جراحة اللمس: محاكاة الجراحة
TrinityCore: إطار عمل MMORPG مفتوح المصدر
؟ إطار عمل المستخدم: إطار عمل غير متزامن مفتوح المصدر مع مجموعة غنية من التجريدات وبرامج تشغيل قواعد البيانات
Windows Terminal: محطة Windows الجديدة
أكثر...
إذا كنت على علم بمشاريع أخرى تستخدم هذه المكتبة، فيرجى إبلاغي بذلك عبر البريد الإلكتروني أو عن طريق إرسال مشكلة.
فلماذا مكتبة تنسيق أخرى؟
هناك الكثير من الطرق للقيام بهذه المهمة، بدءًا من الأساليب القياسية مثل مجموعة وظائف printf وiostreams وحتى مكتبات Boost Format وFastFormat. السبب وراء إنشاء مكتبة جديدة هو أن كل الحلول الموجودة التي وجدتها إما كانت بها مشكلات خطيرة أو لم توفر جميع الميزات التي أحتاجها.
الشيء الجيد في printf
هو أنه سريع جدًا ومتوفر بسهولة كونه جزءًا من مكتبة C القياسية. العيب الرئيسي هو أنه لا يدعم الأنواع المحددة من قبل المستخدم. لدى printf
أيضًا مشكلات تتعلق بالسلامة على الرغم من تخفيفها إلى حد ما باستخدام __attribute__ ((تنسيق (printf، ...)) في دول مجلس التعاون الخليجي. يوجد ملحق POSIX يضيف الوسائط الموضعية المطلوبة لـ i18n إلى printf
ولكنه ليس جزءًا من C99 وقد لا تكون متاحة على بعض المنصات.
من الأفضل توضيح المشكلة الرئيسية المتعلقة بـ iostreams بمثال:
std::cout << std::setprecision(2) << std::fixed << 1.23456 << "n";
وهو كثير من الكتابة مقارنة بـ printf:
printf("%.2fn", 1.23456);
أطلق ماثيو ويلسون، مؤلف كتاب FastFormat، على هذا اسم "جحيم شيفرون". لا تدعم تدفقات iostream الوسائط الموضعية حسب التصميم.
الجزء الجيد هو أن iostreams تدعم الأنواع المحددة من قبل المستخدم وهي آمنة على الرغم من صعوبة معالجة الأخطاء.
هذه مكتبة قوية جدًا تدعم كلاً من سلاسل التنسيق التي تشبه printf
والوسائط الموضعية. عيبها الرئيسي هو الأداء. وفقا لمعايير مختلفة، فهو أبطأ بكثير من الأساليب الأخرى المذكورة هنا. يحتوي Boost Format أيضًا على أوقات إنشاء مفرطة ومشكلات خطيرة في تضخم التعليمات البرمجية (راجع المعايير).
هذه مكتبة مثيرة للاهتمام وسريعة وآمنة ولها حجج موضعية. ومع ذلك، فإن لها قيودًا كبيرة، نقلاً عن مؤلفها:
ثلاث ميزات ليس لها أمل في أن يتم استيعابها في التصميم الحالي هي:
الأصفار البادئة (أو أي حشوة أخرى غير مساوية)
ترميز ثماني/سداسي عشري
مواصفات عرض/محاذاة وقت التشغيل
كما أنه كبير جدًا ويعتمد بشكل كبير على STLSoft، والذي قد يكون مقيدًا للغاية بحيث لا يمكن استخدامه في بعض المشاريع.
هذه ليست مكتبة تنسيق ولكني قررت تضمينها هنا للتأكد من اكتمالها. باعتبارها iostreams، فإنها تعاني من مشكلة خلط النص الحرفي مع الوسائط. المكتبة سريعة جدًا، ولكنها أبطأ في تنسيق الأعداد الصحيحة من fmt::format_to
مع تجميع سلسلة التنسيق وفقًا لمعيار Karma الخاص، راجع تحويل مائة مليون عدد صحيح إلى سلاسل في الثانية.
يتم توزيع {fmt} بموجب ترخيص MIT.
يعتمد قسم تنسيق سلسلة التنسيق في الوثائق على القسم الموجود في وثائق وحدة سلسلة Python. لهذا السبب، يتم توزيع الوثائق بموجب ترخيص Python Software Foundation المتوفر في doc/python-license.txt. ينطبق هذا فقط إذا قمت بتوزيع وثائق {fmt}.
تتم صيانة مكتبة {fmt} بواسطة فيكتور زفيروفيتش (vitaut) بمساهمات من العديد من الأشخاص الآخرين. راجع المساهمين والإصدارات لبعض الأسماء. أخبرنا إذا لم تكن مساهمتك مدرجة أو مذكورة بشكل غير صحيح وسنقوم بتصحيح الأمر.
للإبلاغ عن مشكلة أمنية، يرجى الكشف عنها في الاستشارة الأمنية.
تتم صيانة هذا المشروع من قبل فريق من المتطوعين على أساس جهد معقول. وعلى هذا النحو، يرجى منحنا 90 يومًا على الأقل للعمل على الإصلاح قبل عرضه للعامة.