ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ಎಲ್ಲಾ ಬಳಕೆದಾರರು ಮೊಬೈಲ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ ವೇಗದ ಉಡಾವಣೆ ಮತ್ತು ಸ್ಪಂದಿಸುವ UI ಅನ್ನು ಲಘುವಾಗಿ ತೆಗೆದುಕೊಳ್ಳುತ್ತಾರೆ. ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭಿಸಲು ಬಹಳ ಸಮಯ ತೆಗೆದುಕೊಂಡರೆ, ಬಳಕೆದಾರರು ದುಃಖ ಮತ್ತು ಕೋಪವನ್ನು ಅನುಭವಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತಾರೆ. ನೀವು ಸುಲಭವಾಗಿ ಗ್ರಾಹಕರ ಅನುಭವವನ್ನು ಹಾಳುಮಾಡಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸಲು ಪ್ರಾರಂಭಿಸುವ ಮೊದಲು ಬಳಕೆದಾರರನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಕಳೆದುಕೊಳ್ಳಬಹುದು.

ಡೋಡೋ ಪಿಜ್ಜಾ ಅಪ್ಲಿಕೇಶನ್ ಸರಾಸರಿ ಪ್ರಾರಂಭಿಸಲು 3 ಸೆಕೆಂಡುಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ ಎಂದು ನಾವು ಒಮ್ಮೆ ಕಂಡುಹಿಡಿದಿದ್ದೇವೆ ಮತ್ತು ಕೆಲವು "ಅದೃಷ್ಟವಂತರಿಗೆ" ಇದು 15-20 ಸೆಕೆಂಡುಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ.

ಕಟ್‌ನ ಕೆಳಗೆ ಸುಖಾಂತ್ಯದ ಕಥೆಯಿದೆ: ರಿಯಲ್ಮ್ ಡೇಟಾಬೇಸ್‌ನ ಬೆಳವಣಿಗೆ, ಮೆಮೊರಿ ಸೋರಿಕೆ, ನಾವು ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳನ್ನು ಹೇಗೆ ಸಂಗ್ರಹಿಸಿದ್ದೇವೆ ಮತ್ತು ನಂತರ ನಮ್ಮನ್ನು ಒಟ್ಟಿಗೆ ಎಳೆದುಕೊಂಡು ಎಲ್ಲವನ್ನೂ ಸರಿಪಡಿಸಿದ್ದೇವೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ
ಲೇಖನ ಲೇಖಕ: ಮ್ಯಾಕ್ಸಿಮ್ ಕಚಿಂಕಿನ್ - ಡೋಡೋ ಪಿಜ್ಜಾದಲ್ಲಿ ಆಂಡ್ರಾಯ್ಡ್ ಡೆವಲಪರ್.

ಮೊದಲ ಚಟುವಟಿಕೆಯ onResume() ಗೆ ಅಪ್ಲಿಕೇಶನ್ ಐಕಾನ್ ಮೇಲೆ ಕ್ಲಿಕ್ ಮಾಡುವುದರಿಂದ ಮೂರು ಸೆಕೆಂಡುಗಳು ಅನಂತವಾಗಿರುತ್ತದೆ. ಮತ್ತು ಕೆಲವು ಬಳಕೆದಾರರಿಗೆ, ಆರಂಭಿಕ ಸಮಯವು 15-20 ಸೆಕೆಂಡುಗಳನ್ನು ತಲುಪಿತು. ಇದು ಸಹ ಹೇಗೆ ಸಾಧ್ಯ?

ಓದಲು ಸಮಯವಿಲ್ಲದವರಿಗೆ ಬಹಳ ಚಿಕ್ಕ ಸಾರಾಂಶ
ನಮ್ಮ Realm ಡೇಟಾಬೇಸ್ ಅಂತ್ಯವಿಲ್ಲದಂತೆ ಬೆಳೆಯುತ್ತಿದೆ. ಕೆಲವು ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳನ್ನು ಅಳಿಸಲಾಗಿಲ್ಲ, ಆದರೆ ನಿರಂತರವಾಗಿ ಸಂಗ್ರಹಿಸಲಾಗಿದೆ. ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಸಮಯ ಕ್ರಮೇಣ ಹೆಚ್ಚಾಯಿತು. ನಂತರ ನಾವು ಅದನ್ನು ಸರಿಪಡಿಸಿದ್ದೇವೆ ಮತ್ತು ಆರಂಭಿಕ ಸಮಯವು ಗುರಿಗೆ ಬಂದಿತು - ಇದು 1 ಸೆಕೆಂಡ್‌ಗಿಂತ ಕಡಿಮೆಯಾಯಿತು ಮತ್ತು ಇನ್ನು ಮುಂದೆ ಹೆಚ್ಚಾಗಲಿಲ್ಲ. ಲೇಖನವು ಪರಿಸ್ಥಿತಿಯ ವಿಶ್ಲೇಷಣೆ ಮತ್ತು ಎರಡು ಪರಿಹಾರಗಳನ್ನು ಒಳಗೊಂಡಿದೆ - ತ್ವರಿತ ಮತ್ತು ಸಾಮಾನ್ಯ.

ಸಮಸ್ಯೆಯ ಹುಡುಕಾಟ ಮತ್ತು ವಿಶ್ಲೇಷಣೆ

ಇಂದು, ಯಾವುದೇ ಮೊಬೈಲ್ ಅಪ್ಲಿಕೇಶನ್ ತ್ವರಿತವಾಗಿ ಪ್ರಾರಂಭಿಸಬೇಕು ಮತ್ತು ಸ್ಪಂದಿಸಬೇಕು. ಆದರೆ ಇದು ಕೇವಲ ಮೊಬೈಲ್ ಅಪ್ಲಿಕೇಶನ್ ಬಗ್ಗೆ ಅಲ್ಲ. ಸೇವೆ ಮತ್ತು ಕಂಪನಿಯೊಂದಿಗಿನ ಸಂವಹನದ ಬಳಕೆದಾರರ ಅನುಭವವು ಸಂಕೀರ್ಣ ವಿಷಯವಾಗಿದೆ. ಉದಾಹರಣೆಗೆ, ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ, ವಿತರಣಾ ವೇಗವು ಪಿಜ್ಜಾ ಸೇವೆಯ ಪ್ರಮುಖ ಸೂಚಕಗಳಲ್ಲಿ ಒಂದಾಗಿದೆ. ಡೆಲಿವರಿ ವೇಗವಾಗಿದ್ದರೆ, ಪಿಜ್ಜಾ ಬಿಸಿಯಾಗಿರುತ್ತದೆ ಮತ್ತು ಈಗ ತಿನ್ನಲು ಬಯಸುವ ಗ್ರಾಹಕರು ಹೆಚ್ಚು ಸಮಯ ಕಾಯಬೇಕಾಗಿಲ್ಲ. ಅಪ್ಲಿಕೇಶನ್‌ಗಾಗಿ, ವೇಗದ ಸೇವೆಯ ಭಾವನೆಯನ್ನು ಸೃಷ್ಟಿಸುವುದು ಮುಖ್ಯವಾಗಿದೆ, ಏಕೆಂದರೆ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭಿಸಲು ಕೇವಲ 20 ಸೆಕೆಂಡುಗಳನ್ನು ತೆಗೆದುಕೊಂಡರೆ, ನೀವು ಪಿಜ್ಜಾಕ್ಕಾಗಿ ಎಷ್ಟು ಸಮಯ ಕಾಯಬೇಕಾಗುತ್ತದೆ?

ಮೊದಲಿಗೆ, ಕೆಲವೊಮ್ಮೆ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭಿಸಲು ಒಂದೆರಡು ಸೆಕೆಂಡುಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ ಎಂಬ ಅಂಶವನ್ನು ನಾವೇ ಎದುರಿಸಿದ್ದೇವೆ ಮತ್ತು ನಂತರ ನಾವು ಎಷ್ಟು ಸಮಯ ತೆಗೆದುಕೊಂಡಿದ್ದೇವೆ ಎಂಬುದರ ಕುರಿತು ಇತರ ಸಹೋದ್ಯೋಗಿಗಳಿಂದ ದೂರುಗಳನ್ನು ಕೇಳಲು ಪ್ರಾರಂಭಿಸಿದ್ದೇವೆ. ಆದರೆ ಈ ಪರಿಸ್ಥಿತಿಯನ್ನು ನಿರಂತರವಾಗಿ ಪುನರಾವರ್ತಿಸಲು ನಮಗೆ ಸಾಧ್ಯವಾಗಲಿಲ್ಲ.

ಇದು ಎಷ್ಟು ಸಮಯ? ಈ ಪ್ರಕಾರ Google ದಸ್ತಾವೇಜನ್ನು, ಅಪ್ಲಿಕೇಶನ್‌ನ ಶೀತ ಪ್ರಾರಂಭವು 5 ಸೆಕೆಂಡುಗಳಿಗಿಂತ ಕಡಿಮೆ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಂಡರೆ, ಇದನ್ನು "ಸಾಮಾನ್ಯ" ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ. ಡೋಡೋ ಪಿಜ್ಜಾ ಆಂಡ್ರಾಯ್ಡ್ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ (ಫೈರ್‌ಬೇಸ್ ಮೆಟ್ರಿಕ್ಸ್ ಪ್ರಕಾರ _ಅಪ್ಲಿಕೇಶನ್_ಪ್ರಾರಂಭ) ನಲ್ಲಿ ಶೀತ ಆರಂಭ ಸರಾಸರಿ 3 ಸೆಕೆಂಡುಗಳಲ್ಲಿ - "ಅದ್ಭುತವಾಗಿಲ್ಲ, ಭಯಾನಕವಲ್ಲ," ಅವರು ಹೇಳಿದಂತೆ.

ಆದರೆ ನಂತರ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭಿಸಲು ಬಹಳ, ತುಂಬಾ, ಬಹಳ ಸಮಯ ತೆಗೆದುಕೊಂಡಿತು ಎಂಬ ದೂರುಗಳು ಕಾಣಿಸಿಕೊಳ್ಳಲಾರಂಭಿಸಿದವು! ಮೊದಲಿಗೆ, "ಬಹಳ, ತುಂಬಾ, ಬಹಳ" ಎಂಬುದನ್ನು ಅಳೆಯಲು ನಾವು ನಿರ್ಧರಿಸಿದ್ದೇವೆ. ಮತ್ತು ಇದಕ್ಕಾಗಿ ನಾವು Firebase ಟ್ರೇಸ್ ಅನ್ನು ಬಳಸಿದ್ದೇವೆ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಜಾಡು.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ಈ ಸ್ಟ್ಯಾಂಡರ್ಡ್ ಟ್ರೇಸ್ ಬಳಕೆದಾರರು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ತೆರೆಯುವ ಕ್ಷಣ ಮತ್ತು ಮೊದಲ ಚಟುವಟಿಕೆಯ onResume() ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿದ ಕ್ಷಣದ ನಡುವಿನ ಸಮಯವನ್ನು ಅಳೆಯುತ್ತದೆ. Firebase Console ನಲ್ಲಿ ಈ ಮೆಟ್ರಿಕ್ ಅನ್ನು _app_start ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ. ಅದು ಬದಲಾಯಿತು:

  • ಸರಾಸರಿ ಶೀತ ಪ್ರಾರಂಭದ ಸಮಯವು 95 ಸೆಕೆಂಡುಗಳಿಗಿಂತ ಕಡಿಮೆಯಿದ್ದರೂ ಸಹ, 20 ನೇ ಶೇಕಡಾಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಬಳಕೆದಾರರಿಗೆ ಪ್ರಾರಂಭದ ಸಮಯಗಳು ಸುಮಾರು 5 ಸೆಕೆಂಡುಗಳು (ಕೆಲವು ಇನ್ನೂ ಹೆಚ್ಚು).
  • ಪ್ರಾರಂಭದ ಸಮಯವು ಸ್ಥಿರ ಮೌಲ್ಯವಲ್ಲ, ಆದರೆ ಕಾಲಾನಂತರದಲ್ಲಿ ಬೆಳೆಯುತ್ತದೆ. ಆದರೆ ಕೆಲವೊಮ್ಮೆ ಹನಿಗಳು ಇವೆ. ನಾವು ವಿಶ್ಲೇಷಣೆಯ ಪ್ರಮಾಣವನ್ನು 90 ದಿನಗಳವರೆಗೆ ಹೆಚ್ಚಿಸಿದಾಗ ನಾವು ಈ ಮಾದರಿಯನ್ನು ಕಂಡುಕೊಂಡಿದ್ದೇವೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ಎರಡು ಆಲೋಚನೆಗಳು ಮನಸ್ಸಿಗೆ ಬಂದವು:

  1. ಏನೋ ಸೋರಿಕೆಯಾಗುತ್ತಿದೆ.
  2. ಈ "ಏನೋ" ಬಿಡುಗಡೆಯ ನಂತರ ಮರುಹೊಂದಿಸಲಾಗಿದೆ ಮತ್ತು ನಂತರ ಮತ್ತೆ ಸೋರಿಕೆಯಾಗುತ್ತದೆ.

"ಬಹುಶಃ ಡೇಟಾಬೇಸ್ನೊಂದಿಗೆ ಏನಾದರೂ," ನಾವು ಯೋಚಿಸಿದ್ದೇವೆ ಮತ್ತು ನಾವು ಸರಿಯಾಗಿರುತ್ತೇವೆ. ಮೊದಲನೆಯದಾಗಿ, ನಾವು ಡೇಟಾಬೇಸ್ ಅನ್ನು ಸಂಗ್ರಹವಾಗಿ ಬಳಸುತ್ತೇವೆ; ವಲಸೆಯ ಸಮಯದಲ್ಲಿ ನಾವು ಅದನ್ನು ತೆರವುಗೊಳಿಸುತ್ತೇವೆ. ಎರಡನೆಯದಾಗಿ, ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭವಾದಾಗ ಡೇಟಾಬೇಸ್ ಅನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಎಲ್ಲವೂ ಒಟ್ಟಿಗೆ ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ.

ರಿಯಲ್ಮ್ ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಏನು ತಪ್ಪಾಗಿದೆ

ಮೊದಲ ಸ್ಥಾಪನೆಯಿಂದ ಮತ್ತು ಸಕ್ರಿಯ ಬಳಕೆಯ ಸಮಯದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ನ ಜೀವನದಲ್ಲಿ ಡೇಟಾಬೇಸ್‌ನ ವಿಷಯಗಳು ಹೇಗೆ ಬದಲಾಗುತ್ತವೆ ಎಂಬುದನ್ನು ನಾವು ಪರಿಶೀಲಿಸಲು ಪ್ರಾರಂಭಿಸಿದ್ದೇವೆ. ನೀವು ಮೂಲಕ ರಿಯಲ್ಮ್ ಡೇಟಾಬೇಸ್‌ನ ವಿಷಯಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಸ್ಟೆಥೋ ಅಥವಾ ಫೈಲ್ ಅನ್ನು ತೆರೆಯುವ ಮೂಲಕ ಹೆಚ್ಚು ವಿವರವಾಗಿ ಮತ್ತು ಸ್ಪಷ್ಟವಾಗಿ ರಿಯಲ್ಮ್ ಸ್ಟುಡಿಯೋ. ADB ಮೂಲಕ ಡೇಟಾಬೇಸ್‌ನ ವಿಷಯಗಳನ್ನು ವೀಕ್ಷಿಸಲು, Realm ಡೇಟಾಬೇಸ್ ಫೈಲ್ ಅನ್ನು ನಕಲಿಸಿ:

adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME}

ಡೇಟಾಬೇಸ್‌ನ ವಿಷಯಗಳನ್ನು ವಿವಿಧ ಸಮಯಗಳಲ್ಲಿ ನೋಡಿದ ನಂತರ, ಒಂದು ನಿರ್ದಿಷ್ಟ ಪ್ರಕಾರದ ವಸ್ತುಗಳ ಸಂಖ್ಯೆ ನಿರಂತರವಾಗಿ ಹೆಚ್ಚುತ್ತಿದೆ ಎಂದು ನಾವು ಕಂಡುಕೊಂಡಿದ್ದೇವೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ
ಚಿತ್ರವು ಎರಡು ಫೈಲ್‌ಗಳಿಗಾಗಿ ರಿಯಲ್ಮ್ ಸ್ಟುಡಿಯೊದ ತುಣುಕನ್ನು ತೋರಿಸುತ್ತದೆ: ಎಡಭಾಗದಲ್ಲಿ - ಅನುಸ್ಥಾಪನೆಯ ನಂತರ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಅಪ್ಲಿಕೇಶನ್ ಬೇಸ್, ಬಲಭಾಗದಲ್ಲಿ - ಸಕ್ರಿಯ ಬಳಕೆಯ ನಂತರ. ವಸ್ತುಗಳ ಸಂಖ್ಯೆಯನ್ನು ನೋಡಬಹುದು ImageEntity и MoneyType ಗಮನಾರ್ಹವಾಗಿ ಬೆಳೆದಿದೆ (ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಪ್ರತಿ ಪ್ರಕಾರದ ವಸ್ತುಗಳ ಸಂಖ್ಯೆಯನ್ನು ತೋರಿಸುತ್ತದೆ).

ಡೇಟಾಬೇಸ್ ಬೆಳವಣಿಗೆ ಮತ್ತು ಆರಂಭಿಕ ಸಮಯದ ನಡುವಿನ ಸಂಬಂಧ

ಅನಿಯಂತ್ರಿತ ಡೇಟಾಬೇಸ್ ಬೆಳವಣಿಗೆ ತುಂಬಾ ಕೆಟ್ಟದಾಗಿದೆ. ಆದರೆ ಇದು ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಸಮಯದ ಮೇಲೆ ಹೇಗೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ? ActivityManager ಮೂಲಕ ಇದನ್ನು ಅಳೆಯುವುದು ತುಂಬಾ ಸುಲಭ. ಆಂಡ್ರಾಯ್ಡ್ 4.4 ರಿಂದ, ಲಾಗ್‌ಕ್ಯಾಟ್ ಪ್ರದರ್ಶಿಸಲಾದ ಸ್ಟ್ರಿಂಗ್ ಮತ್ತು ಸಮಯದೊಂದಿಗೆ ಲಾಗ್ ಅನ್ನು ಪ್ರದರ್ಶಿಸುತ್ತದೆ. ಈ ಸಮಯವು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಕ್ಷಣದಿಂದ ಚಟುವಟಿಕೆಯ ರೆಂಡರಿಂಗ್ ಅಂತ್ಯದವರೆಗೆ ಮಧ್ಯಂತರಕ್ಕೆ ಸಮಾನವಾಗಿರುತ್ತದೆ. ಈ ಸಮಯದಲ್ಲಿ, ಈ ಕೆಳಗಿನ ಘಟನೆಗಳು ಸಂಭವಿಸುತ್ತವೆ:

  • ಪ್ರಕ್ರಿಯೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ.
  • ವಸ್ತುಗಳ ಪ್ರಾರಂಭ.
  • ಚಟುವಟಿಕೆಗಳ ರಚನೆ ಮತ್ತು ಪ್ರಾರಂಭ.
  • ಲೇಔಟ್ ರಚಿಸಲಾಗುತ್ತಿದೆ.
  • ಅಪ್ಲಿಕೇಶನ್ ರೆಂಡರಿಂಗ್.

ನಮಗೆ ಸರಿಹೊಂದುತ್ತದೆ. ನೀವು -S ಮತ್ತು -W ಫ್ಲ್ಯಾಗ್‌ಗಳೊಂದಿಗೆ ADB ಅನ್ನು ರನ್ ಮಾಡಿದರೆ, ನೀವು ಪ್ರಾರಂಭದ ಸಮಯದೊಂದಿಗೆ ವಿಸ್ತೃತ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಪಡೆಯಬಹುದು:

adb shell am start -S -W ru.dodopizza.app/.MainActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAIN

ಅಲ್ಲಿಂದ ಹಿಡಿದುಕೊಂಡರೆ grep -i WaitTime ಸಮಯ, ನೀವು ಈ ಮೆಟ್ರಿಕ್‌ನ ಸಂಗ್ರಹವನ್ನು ಸ್ವಯಂಚಾಲಿತಗೊಳಿಸಬಹುದು ಮತ್ತು ಫಲಿತಾಂಶಗಳನ್ನು ದೃಷ್ಟಿಗೋಚರವಾಗಿ ನೋಡಬಹುದು. ಕೆಳಗಿನ ಗ್ರಾಫ್ ಅಪ್ಲಿಕೇಶನ್‌ನ ಕೋಲ್ಡ್ ಸ್ಟಾರ್ಟ್‌ಗಳ ಸಂಖ್ಯೆಯ ಮೇಲೆ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಸಮಯದ ಅವಲಂಬನೆಯನ್ನು ತೋರಿಸುತ್ತದೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ಅದೇ ಸಮಯದಲ್ಲಿ, ಡೇಟಾಬೇಸ್ನ ಗಾತ್ರ ಮತ್ತು ಬೆಳವಣಿಗೆಯ ನಡುವಿನ ಸಂಬಂಧದ ಅದೇ ಸ್ವಭಾವವು 4 MB ಯಿಂದ 15 MB ವರೆಗೆ ಬೆಳೆಯಿತು. ಒಟ್ಟಾರೆಯಾಗಿ, ಕಾಲಾನಂತರದಲ್ಲಿ (ಶೀತದ ಪ್ರಾರಂಭದ ಬೆಳವಣಿಗೆಯೊಂದಿಗೆ), ಅಪ್ಲಿಕೇಶನ್ ಉಡಾವಣಾ ಸಮಯ ಮತ್ತು ಡೇಟಾಬೇಸ್ನ ಗಾತ್ರ ಎರಡೂ ಹೆಚ್ಚಾಯಿತು ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ. ನಮ್ಮ ಕೈಯಲ್ಲಿ ಒಂದು ಊಹೆ ಇದೆ. ಈಗ ಅವಲಂಬನೆಯನ್ನು ಖಚಿತಪಡಿಸಲು ಮಾತ್ರ ಉಳಿದಿದೆ. ಆದ್ದರಿಂದ, ನಾವು "ಸೋರಿಕೆಗಳನ್ನು" ತೆಗೆದುಹಾಕಲು ನಿರ್ಧರಿಸಿದ್ದೇವೆ ಮತ್ತು ಇದು ಉಡಾವಣೆಯನ್ನು ವೇಗಗೊಳಿಸುತ್ತದೆಯೇ ಎಂದು ನೋಡೋಣ.

ಅಂತ್ಯವಿಲ್ಲದ ಡೇಟಾಬೇಸ್ ಬೆಳವಣಿಗೆಗೆ ಕಾರಣಗಳು

"ಸೋರಿಕೆಯನ್ನು" ತೆಗೆದುಹಾಕುವ ಮೊದಲು, ಅವರು ಮೊದಲ ಸ್ಥಾನದಲ್ಲಿ ಏಕೆ ಕಾಣಿಸಿಕೊಂಡರು ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಯೋಗ್ಯವಾಗಿದೆ. ಇದನ್ನು ಮಾಡಲು, ರಿಯಲ್ಮ್ ಏನೆಂದು ನೆನಪಿಸೋಣ.

ಕ್ಷೇತ್ರವು ಸಂಬಂಧವಿಲ್ಲದ ಡೇಟಾಬೇಸ್ ಆಗಿದೆ. Android ನಲ್ಲಿ ಎಷ್ಟು ORM ಸಂಬಂಧಿತ ಡೇಟಾಬೇಸ್‌ಗಳನ್ನು ವಿವರಿಸಲಾಗಿದೆಯೋ ಅದೇ ರೀತಿಯಲ್ಲಿ ವಸ್ತುಗಳ ನಡುವಿನ ಸಂಬಂಧಗಳನ್ನು ವಿವರಿಸಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ. ಅದೇ ಸಮಯದಲ್ಲಿ, ರಿಯಲ್ಮ್ ಕನಿಷ್ಠ ಪ್ರಮಾಣದ ರೂಪಾಂತರಗಳು ಮತ್ತು ಮ್ಯಾಪಿಂಗ್‌ಗಳೊಂದಿಗೆ ವಸ್ತುಗಳನ್ನು ನೇರವಾಗಿ ಮೆಮೊರಿಯಲ್ಲಿ ಸಂಗ್ರಹಿಸುತ್ತದೆ. ಡಿಸ್ಕ್‌ನಿಂದ ಡೇಟಾವನ್ನು ತ್ವರಿತವಾಗಿ ಓದಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಇದು ರಿಯಲ್ಮ್‌ನ ಶಕ್ತಿ ಮತ್ತು ಅದು ಏಕೆ ಪ್ರೀತಿಸಲ್ಪಟ್ಟಿದೆ.

(ಈ ಲೇಖನದ ಉದ್ದೇಶಗಳಿಗಾಗಿ, ಈ ವಿವರಣೆಯು ನಮಗೆ ಸಾಕಾಗುತ್ತದೆ. ನೀವು ತಂಪಾಗಿರುವ ಸಾಮ್ರಾಜ್ಯದ ಕುರಿತು ಇನ್ನಷ್ಟು ಓದಬಹುದು ದಸ್ತಾವೇಜನ್ನು ಅಥವಾ ಅವರಲ್ಲಿ ಅಕಾಡೆಮಿ).

ಅನೇಕ ಡೆವಲಪರ್‌ಗಳು ಸಂಬಂಧಿತ ಡೇಟಾಬೇಸ್‌ಗಳೊಂದಿಗೆ ಹೆಚ್ಚು ಕೆಲಸ ಮಾಡಲು ಒಗ್ಗಿಕೊಂಡಿರುತ್ತಾರೆ (ಉದಾಹರಣೆಗೆ, ಹುಡ್ ಅಡಿಯಲ್ಲಿ SQL ನೊಂದಿಗೆ ORM ಡೇಟಾಬೇಸ್‌ಗಳು). ಮತ್ತು ಕ್ಯಾಸ್ಕೇಡಿಂಗ್ ಡೇಟಾ ಅಳಿಸುವಿಕೆಯಂತಹ ವಿಷಯಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಕೊಟ್ಟಿರುವಂತೆ ತೋರುತ್ತವೆ. ಆದರೆ ಕ್ಷೇತ್ರದಲ್ಲಿ ಅಲ್ಲ.

ಮೂಲಕ, ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯವನ್ನು ದೀರ್ಘಕಾಲದವರೆಗೆ ಕೇಳಲಾಗಿದೆ. ಈ ಪರಿಷ್ಕರಣೆ и ಇನ್ನೊಂದು, ಅದರೊಂದಿಗೆ ಸಂಬಂಧಿಸಿದೆ, ಸಕ್ರಿಯವಾಗಿ ಚರ್ಚಿಸಲಾಗಿದೆ. ಅದು ಬೇಗನೇ ಆಗುತ್ತದೆ ಎಂಬ ಭಾವನೆ ಇತ್ತು. ಆದರೆ ನಂತರ ಎಲ್ಲವನ್ನೂ ಬಲವಾದ ಮತ್ತು ದುರ್ಬಲ ಲಿಂಕ್‌ಗಳ ಪರಿಚಯಕ್ಕೆ ಅನುವಾದಿಸಲಾಗಿದೆ, ಅದು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸುತ್ತದೆ. ಈ ಕಾರ್ಯದಲ್ಲಿ ಸಾಕಷ್ಟು ಉತ್ಸಾಹಭರಿತ ಮತ್ತು ಸಕ್ರಿಯರಾಗಿದ್ದರು ವಿನಂತಿಯನ್ನು ಎಳೆಯಿರಿಆಂತರಿಕ ತೊಂದರೆಗಳಿಂದಾಗಿ ಸದ್ಯಕ್ಕೆ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ.

ಕ್ಯಾಸ್ಕೇಡಿಂಗ್ ಅಳಿಸದೆಯೇ ಡೇಟಾ ಸೋರಿಕೆ

ನೀವು ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲದ ಕ್ಯಾಸ್ಕೇಡಿಂಗ್ ಅಳಿಸುವಿಕೆಯನ್ನು ಅವಲಂಬಿಸಿದ್ದರೆ ಡೇಟಾ ಎಷ್ಟು ನಿಖರವಾಗಿ ಸೋರಿಕೆಯಾಗುತ್ತದೆ? ನೀವು ನೆಸ್ಟೆಡ್ ರಿಯಲ್ಮ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿದ್ದರೆ, ನಂತರ ಅವುಗಳನ್ನು ಅಳಿಸಬೇಕು.
(ಬಹುತೇಕ) ನೈಜ ಉದಾಹರಣೆಯನ್ನು ನೋಡೋಣ. ನಮಗೆ ಒಂದು ವಸ್ತುವಿದೆ CartItemEntity:

@RealmClass
class CartItemEntity(
 @PrimaryKey
 override var id: String? = null,
 ...
 var name: String = "",
 var description: String = "",
 var image: ImageEntity? = null,
 var category: String = MENU_CATEGORY_UNKNOWN_ID,
 var customizationEntity: CustomizationEntity? = null,
 var cartComboProducts: RealmList<CartProductEntity> = RealmList(),
 ...
) : RealmObject()

ಕಾರ್ಟ್‌ನಲ್ಲಿರುವ ಉತ್ಪನ್ನವು ಚಿತ್ರ ಸೇರಿದಂತೆ ವಿವಿಧ ಕ್ಷೇತ್ರಗಳನ್ನು ಹೊಂದಿದೆ ImageEntity, ಕಸ್ಟಮೈಸ್ ಮಾಡಿದ ಪದಾರ್ಥಗಳು CustomizationEntity. ಅಲ್ಲದೆ, ಕಾರ್ಟ್‌ನಲ್ಲಿರುವ ಉತ್ಪನ್ನವು ತನ್ನದೇ ಆದ ಉತ್ಪನ್ನಗಳೊಂದಿಗೆ ಸಂಯೋಜನೆಯಾಗಿರಬಹುದು RealmList (CartProductEntity). ಪಟ್ಟಿ ಮಾಡಲಾದ ಎಲ್ಲಾ ಕ್ಷೇತ್ರಗಳು ರಿಯಲ್ಮ್ ಆಬ್ಜೆಕ್ಟ್ಗಳಾಗಿವೆ. ನಾವು ಅದೇ ಐಡಿಯೊಂದಿಗೆ ಹೊಸ ವಸ್ತುವನ್ನು (copyToRealm() / copyToRealmOrUpdate()) ಸೇರಿಸಿದರೆ, ಈ ವಸ್ತುವನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ತಿದ್ದಿ ಬರೆಯಲಾಗುತ್ತದೆ. ಆದರೆ ಎಲ್ಲಾ ಆಂತರಿಕ ವಸ್ತುಗಳು (ಚಿತ್ರ, ಗ್ರಾಹಕೀಕರಣಎಂಟಿಟಿ ಮತ್ತು ಕಾರ್ಟ್‌ಕಾಂಬೋಪ್ರೊಡಕ್ಟ್ಸ್) ಪೋಷಕರೊಂದಿಗೆ ಸಂಪರ್ಕವನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತವೆ ಮತ್ತು ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಉಳಿಯುತ್ತವೆ.

ಅವರೊಂದಿಗಿನ ಸಂಪರ್ಕವು ಕಳೆದುಹೋದ ಕಾರಣ, ನಾವು ಇನ್ನು ಮುಂದೆ ಅವುಗಳನ್ನು ಓದುವುದಿಲ್ಲ ಅಥವಾ ಅಳಿಸುವುದಿಲ್ಲ (ನಾವು ಅವುಗಳನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಪ್ರವೇಶಿಸದ ಹೊರತು ಅಥವಾ ಸಂಪೂರ್ಣ "ಟೇಬಲ್" ಅನ್ನು ತೆರವುಗೊಳಿಸದ ಹೊರತು). ನಾವು ಇದನ್ನು "ಮೆಮೊರಿ ಲೀಕ್ಸ್" ಎಂದು ಕರೆದಿದ್ದೇವೆ.

ನಾವು ರಿಯಲ್ಮ್‌ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ, ನಾವು ಎಲ್ಲಾ ಅಂಶಗಳ ಮೂಲಕ ಸ್ಪಷ್ಟವಾಗಿ ಹೋಗಬೇಕು ಮತ್ತು ಅಂತಹ ಕಾರ್ಯಾಚರಣೆಗಳ ಮೊದಲು ಎಲ್ಲವನ್ನೂ ಸ್ಪಷ್ಟವಾಗಿ ಅಳಿಸಬೇಕು. ಇದನ್ನು ಮಾಡಬಹುದು, ಉದಾಹರಣೆಗೆ, ಈ ರೀತಿ:

val entity = realm.where(CartItemEntity::class.java).equalTo("id", id).findFirst()
if (first != null) {
 deleteFromRealm(first.image)
 deleteFromRealm(first.customizationEntity)
 for(cartProductEntity in first.cartComboProducts) {
   deleteFromRealm(cartProductEntity)
 }
 first.deleteFromRealm()
}
// и потом уже сохраняем

ನೀವು ಇದನ್ನು ಮಾಡಿದರೆ, ಎಲ್ಲವೂ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, ಇಮೇಜ್, ಕಸ್ಟಮೈಸೇಶನ್‌ಎಂಟಿಟಿ ಮತ್ತು ಕಾರ್ಟ್‌ಕಾಂಬೋಪ್ರೊಡಕ್ಟ್‌ಗಳ ಒಳಗೆ ಯಾವುದೇ ನೆಸ್ಟೆಡ್ ರಿಯಲ್ಮ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳಿಲ್ಲ ಎಂದು ನಾವು ಭಾವಿಸುತ್ತೇವೆ, ಆದ್ದರಿಂದ ಯಾವುದೇ ನೆಸ್ಟೆಡ್ ಲೂಪ್‌ಗಳು ಮತ್ತು ಅಳಿಸುವಿಕೆಗಳಿಲ್ಲ.

"ತ್ವರಿತ" ಪರಿಹಾರ

ನಾವು ಮಾಡಲು ನಿರ್ಧರಿಸಿದ ಮೊದಲ ವಿಷಯವೆಂದರೆ ವೇಗವಾಗಿ ಬೆಳೆಯುತ್ತಿರುವ ವಸ್ತುಗಳನ್ನು ಸ್ವಚ್ಛಗೊಳಿಸುವುದು ಮತ್ತು ಇದು ನಮ್ಮ ಮೂಲ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸುತ್ತದೆಯೇ ಎಂದು ನೋಡಲು ಫಲಿತಾಂಶಗಳನ್ನು ಪರಿಶೀಲಿಸಿ. ಮೊದಲನೆಯದಾಗಿ, ಸರಳ ಮತ್ತು ಅತ್ಯಂತ ಅರ್ಥಗರ್ಭಿತ ಪರಿಹಾರವನ್ನು ಮಾಡಲಾಯಿತು, ಅವುಗಳೆಂದರೆ: ಪ್ರತಿಯೊಂದು ವಸ್ತುವು ಅದರ ಮಕ್ಕಳನ್ನು ತೆಗೆದುಹಾಕಲು ಜವಾಬ್ದಾರರಾಗಿರಬೇಕು. ಇದನ್ನು ಮಾಡಲು, ನಾವು ಅದರ ನೆಸ್ಟೆಡ್ ರಿಯಲ್ಮ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳ ಪಟ್ಟಿಯನ್ನು ಹಿಂತಿರುಗಿಸುವ ಇಂಟರ್ಫೇಸ್ ಅನ್ನು ಪರಿಚಯಿಸಿದ್ದೇವೆ:

interface NestedEntityAware {
 fun getNestedEntities(): Collection<RealmObject?>
}

ಮತ್ತು ನಾವು ಅದನ್ನು ನಮ್ಮ ರಿಯಲ್ಮ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳಲ್ಲಿ ಅಳವಡಿಸಿದ್ದೇವೆ:

@RealmClass
class DataPizzeriaEntity(
 @PrimaryKey
 var id: String? = null,
 var name: String? = null,
 var coordinates: CoordinatesEntity? = null,
 var deliverySchedule: ScheduleEntity? = null,
 var restaurantSchedule: ScheduleEntity? = null,
 ...
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       coordinates,
       deliverySchedule,
       restaurantSchedule
   )
 }
}

В getNestedEntities ನಾವು ಎಲ್ಲಾ ಮಕ್ಕಳನ್ನು ಫ್ಲಾಟ್ ಪಟ್ಟಿಯಾಗಿ ಹಿಂತಿರುಗಿಸುತ್ತೇವೆ. ಮತ್ತು ಪ್ರತಿ ಮಗುವಿನ ವಸ್ತುವು NestedEntityAware ಇಂಟರ್ಫೇಸ್ ಅನ್ನು ಸಹ ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು, ಇದು ಅಳಿಸಲು ಆಂತರಿಕ ರಿಯಲ್ಮ್ ವಸ್ತುಗಳನ್ನು ಹೊಂದಿದೆ ಎಂದು ಸೂಚಿಸುತ್ತದೆ, ಉದಾಹರಣೆಗೆ ScheduleEntity:

@RealmClass
class ScheduleEntity(
 var monday: DayOfWeekEntity? = null,
 var tuesday: DayOfWeekEntity? = null,
 var wednesday: DayOfWeekEntity? = null,
 var thursday: DayOfWeekEntity? = null,
 var friday: DayOfWeekEntity? = null,
 var saturday: DayOfWeekEntity? = null,
 var sunday: DayOfWeekEntity? = null
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       monday, tuesday, wednesday, thursday, friday, saturday, sunday
   )
 }
}

ಮತ್ತು ಹೀಗೆ, ವಸ್ತುಗಳ ಗೂಡುಕಟ್ಟುವಿಕೆಯನ್ನು ಪುನರಾವರ್ತಿಸಬಹುದು.

ನಂತರ ನಾವು ಎಲ್ಲಾ ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ಅಳಿಸುವ ವಿಧಾನವನ್ನು ಬರೆಯುತ್ತೇವೆ. ವಿಧಾನ (ವಿಸ್ತರಣೆಯಾಗಿ ಮಾಡಲಾಗಿದೆ) deleteAllNestedEntities ಎಲ್ಲಾ ಉನ್ನತ ಮಟ್ಟದ ವಸ್ತುಗಳು ಮತ್ತು ವಿಧಾನವನ್ನು ಪಡೆಯುತ್ತದೆ deleteNestedRecursively NestedEntityAware ಇಂಟರ್ಫೇಸ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಎಲ್ಲಾ ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ತೆಗೆದುಹಾಕುತ್ತದೆ:

fun <T> Realm.deleteAllNestedEntities(entities: Collection<T>,
 entityClass: Class<out RealmObject>,
 idMapper: (T) -> String,
 idFieldName : String = "id"
 ) {

 val existedObjects = where(entityClass)
     .`in`(idFieldName, entities.map(idMapper).toTypedArray())
     .findAll()

 deleteNestedRecursively(existedObjects)
}

private fun Realm.deleteNestedRecursively(entities: Collection<RealmObject?>) {
 for(entity in entities) {
   entity?.let { realmObject ->
     if (realmObject is NestedEntityAware) {
       deleteNestedRecursively((realmObject as NestedEntityAware).getNestedEntities())
     }
     realmObject.deleteFromRealm()
   }
 }
}

ನಾವು ವೇಗವಾಗಿ ಬೆಳೆಯುತ್ತಿರುವ ವಸ್ತುಗಳೊಂದಿಗೆ ಇದನ್ನು ಮಾಡಿದ್ದೇವೆ ಮತ್ತು ಏನಾಯಿತು ಎಂಬುದನ್ನು ಪರಿಶೀಲಿಸಿದ್ದೇವೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ಪರಿಣಾಮವಾಗಿ, ನಾವು ಈ ಪರಿಹಾರದೊಂದಿಗೆ ಮುಚ್ಚಿದ ಆ ವಸ್ತುಗಳು ಬೆಳೆಯುವುದನ್ನು ನಿಲ್ಲಿಸಿದವು. ಮತ್ತು ಬೇಸ್ನ ಒಟ್ಟಾರೆ ಬೆಳವಣಿಗೆ ನಿಧಾನವಾಯಿತು, ಆದರೆ ನಿಲ್ಲಲಿಲ್ಲ.

"ಸಾಮಾನ್ಯ" ಪರಿಹಾರ

ಬೇಸ್ ಹೆಚ್ಚು ನಿಧಾನವಾಗಿ ಬೆಳೆಯಲು ಪ್ರಾರಂಭಿಸಿದರೂ, ಅದು ಇನ್ನೂ ಬೆಳೆಯಿತು. ಆದ್ದರಿಂದ ನಾವು ಮತ್ತಷ್ಟು ನೋಡಲು ಪ್ರಾರಂಭಿಸಿದೆವು. ನಮ್ಮ ಯೋಜನೆಯು Realm ನಲ್ಲಿ ಡೇಟಾ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳುವಿಕೆಯನ್ನು ಅತ್ಯಂತ ಸಕ್ರಿಯವಾಗಿ ಬಳಸುತ್ತದೆ. ಆದ್ದರಿಂದ, ಪ್ರತಿ ವಸ್ತುವಿಗೆ ಎಲ್ಲಾ ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳನ್ನು ಬರೆಯುವುದು ಕಾರ್ಮಿಕ-ತೀವ್ರವಾಗಿರುತ್ತದೆ, ಜೊತೆಗೆ ದೋಷಗಳ ಅಪಾಯವು ಹೆಚ್ಚಾಗುತ್ತದೆ, ಏಕೆಂದರೆ ಕೋಡ್ ಅನ್ನು ಬದಲಾಯಿಸುವಾಗ ನೀವು ವಸ್ತುಗಳನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಲು ಮರೆಯಬಹುದು.

ನಾನು ಇಂಟರ್ಫೇಸ್‌ಗಳನ್ನು ಬಳಸುವುದಿಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ನಾನು ಬಯಸುತ್ತೇನೆ, ಆದರೆ ಎಲ್ಲವೂ ತನ್ನದೇ ಆದ ಮೇಲೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ.

ನಾವು ಏನನ್ನಾದರೂ ಸ್ವಂತವಾಗಿ ಕೆಲಸ ಮಾಡಲು ಬಯಸಿದಾಗ, ನಾವು ಪ್ರತಿಫಲನವನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ. ಇದನ್ನು ಮಾಡಲು, ನಾವು ಪ್ರತಿ ವರ್ಗ ಕ್ಷೇತ್ರದ ಮೂಲಕ ಹೋಗಬಹುದು ಮತ್ತು ಅದು ರಿಯಲ್ಮ್ ಆಬ್ಜೆಕ್ಟ್ ಅಥವಾ ವಸ್ತುಗಳ ಪಟ್ಟಿಯೇ ಎಂದು ಪರಿಶೀಲಿಸಬಹುದು:

RealmModel::class.java.isAssignableFrom(field.type)

RealmList::class.java.isAssignableFrom(field.type)

ಕ್ಷೇತ್ರವು RealmModel ಅಥವಾ RealmList ಆಗಿದ್ದರೆ, ಈ ಕ್ಷೇತ್ರದ ವಸ್ತುವನ್ನು ನೆಸ್ಟೆಡ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳ ಪಟ್ಟಿಗೆ ಸೇರಿಸಿ. ನಾವು ಮೇಲೆ ಮಾಡಿದಂತೆಯೇ ಎಲ್ಲವೂ ಒಂದೇ ಆಗಿರುತ್ತದೆ, ಇಲ್ಲಿ ಮಾತ್ರ ಅದು ಸ್ವತಃ ಮಾಡಲ್ಪಡುತ್ತದೆ. ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯ ವಿಧಾನವು ತುಂಬಾ ಸರಳವಾಗಿದೆ ಮತ್ತು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

fun <T : Any> Realm.cascadeDelete(entities: Collection<T?>) {
 if(entities.isEmpty()) {
   return
 }

 entities.filterNotNull().let { notNullEntities ->
   notNullEntities
       .filterRealmObject()
       .flatMap { realmObject -> getNestedRealmObjects(realmObject) }
       .also { realmObjects -> cascadeDelete(realmObjects) }

   notNullEntities
       .forEach { entity ->
         if((entity is RealmObject) && entity.isValid) {
           entity.deleteFromRealm()
         }
       }
 }
}

ವಿಸ್ತರಣೆ filterRealmObject ರಿಯಲ್ಮ್ ವಸ್ತುಗಳನ್ನು ಮಾತ್ರ ಫಿಲ್ಟರ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ರವಾನಿಸುತ್ತದೆ. ವಿಧಾನ getNestedRealmObjects ಪ್ರತಿಬಿಂಬದ ಮೂಲಕ, ಇದು ಎಲ್ಲಾ ನೆಸ್ಟೆಡ್ ರಿಯಲ್ಮ್ ವಸ್ತುಗಳನ್ನು ಹುಡುಕುತ್ತದೆ ಮತ್ತು ಅವುಗಳನ್ನು ರೇಖೀಯ ಪಟ್ಟಿಗೆ ಇರಿಸುತ್ತದೆ. ನಂತರ ನಾವು ಅದೇ ಕೆಲಸವನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ಮಾಡುತ್ತೇವೆ. ಅಳಿಸುವಾಗ, ನೀವು ವಸ್ತುವನ್ನು ಮಾನ್ಯತೆಗಾಗಿ ಪರಿಶೀಲಿಸಬೇಕು isValid, ಏಕೆಂದರೆ ವಿಭಿನ್ನ ಮೂಲ ವಸ್ತುಗಳು ಒಂದೇ ರೀತಿಯ ಗೂಡುಗಳನ್ನು ಹೊಂದಿರಬಹುದು. ಇದನ್ನು ತಪ್ಪಿಸುವುದು ಉತ್ತಮ ಮತ್ತು ಹೊಸ ವಸ್ತುಗಳನ್ನು ರಚಿಸುವಾಗ ಸ್ವಯಂ-ಜನರೇಶನ್ ಐಡಿಯನ್ನು ಬಳಸುವುದು ಉತ್ತಮ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

getNestedRealmObjects ವಿಧಾನದ ಸಂಪೂರ್ಣ ಅನುಷ್ಠಾನ

private fun getNestedRealmObjects(realmObject: RealmObject) : List<RealmObject> {
 val nestedObjects = mutableListOf<RealmObject>()
 val fields = realmObject.javaClass.superclass.declaredFields

// Проверяем каждое поле, не является ли оно RealmModel или списком RealmList
 fields.forEach { field ->
   when {
     RealmModel::class.java.isAssignableFrom(field.type) -> {
       try {
         val child = getChildObjectByField(realmObject, field)
         child?.let {
           if (isInstanceOfRealmObject(it)) {
             nestedObjects.add(child as RealmObject)
           }
         }
       } catch (e: Exception) { ... }
     }

     RealmList::class.java.isAssignableFrom(field.type) -> {
       try {
         val childList = getChildObjectByField(realmObject, field)
         childList?.let { list ->
           (list as RealmList<*>).forEach {
             if (isInstanceOfRealmObject(it)) {
               nestedObjects.add(it as RealmObject)
             }
           }
         }
       } catch (e: Exception) { ... }
     }
   }
 }

 return nestedObjects
}

private fun getChildObjectByField(realmObject: RealmObject, field: Field): Any? {
 val methodName = "get${field.name.capitalize()}"
 val method = realmObject.javaClass.getMethod(methodName)
 return method.invoke(realmObject)
}

ಪರಿಣಾಮವಾಗಿ, ನಮ್ಮ ಕ್ಲೈಂಟ್ ಕೋಡ್‌ನಲ್ಲಿ ನಾವು ಪ್ರತಿ ಡೇಟಾ ಮಾರ್ಪಾಡು ಕಾರ್ಯಾಚರಣೆಗೆ "ಕ್ಯಾಸ್ಕೇಡಿಂಗ್ ಡಿಲೀಟ್" ಅನ್ನು ಬಳಸುತ್ತೇವೆ. ಉದಾಹರಣೆಗೆ, ಇನ್ಸರ್ಟ್ ಕಾರ್ಯಾಚರಣೆಗೆ ಇದು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

override fun <T : Entity> insert(
 entityInformation: EntityInformation,
 entities: Collection<T>): Collection<T> = entities.apply {
 realmInstance.cascadeDelete(getManagedEntities(entityInformation, this))
 realmInstance.copyFromRealm(
     realmInstance
         .copyToRealmOrUpdate(this.map { entity -> entity as RealmModel }
 ))
}

ಮೊದಲು ವಿಧಾನ getManagedEntities ಎಲ್ಲಾ ಸೇರಿಸಿದ ವಸ್ತುಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ, ಮತ್ತು ನಂತರ ವಿಧಾನ cascadeDelete ಹೊಸದನ್ನು ಬರೆಯುವ ಮೊದಲು ಎಲ್ಲಾ ಸಂಗ್ರಹಿಸಿದ ವಸ್ತುಗಳನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ಅಳಿಸುತ್ತದೆ. ನಾವು ಅಪ್ಲಿಕೇಶನ್‌ನಾದ್ಯಂತ ಈ ವಿಧಾನವನ್ನು ಬಳಸುತ್ತೇವೆ. ರಿಯಲ್ಮ್ನಲ್ಲಿ ಮೆಮೊರಿ ಸೋರಿಕೆಯು ಸಂಪೂರ್ಣವಾಗಿ ಹೋಗಿದೆ. ಅಪ್ಲಿಕೇಶನ್‌ನ ಕೋಲ್ಡ್ ಸ್ಟಾರ್ಟ್‌ಗಳ ಸಂಖ್ಯೆಯ ಮೇಲೆ ಆರಂಭಿಕ ಸಮಯದ ಅವಲಂಬನೆಯ ಅದೇ ಅಳತೆಯನ್ನು ನಡೆಸಿದ ನಂತರ, ನಾವು ಫಲಿತಾಂಶವನ್ನು ನೋಡುತ್ತೇವೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳ ಸ್ವಯಂಚಾಲಿತ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯ ಸಮಯದಲ್ಲಿ ಶೀತ ಪ್ರಾರಂಭಗಳ ಸಂಖ್ಯೆಯ ಮೇಲೆ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಸಮಯದ ಅವಲಂಬನೆಯನ್ನು ಹಸಿರು ರೇಖೆ ತೋರಿಸುತ್ತದೆ.

ಫಲಿತಾಂಶಗಳು ಮತ್ತು ತೀರ್ಮಾನಗಳು

ನಿರಂತರವಾಗಿ ಬೆಳೆಯುತ್ತಿರುವ Realm ಡೇಟಾಬೇಸ್ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ನಿಧಾನವಾಗಿ ಪ್ರಾರಂಭಿಸಲು ಕಾರಣವಾಯಿತು. ನೆಸ್ಟೆಡ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳ ನಮ್ಮದೇ ಆದ "ಕ್ಯಾಸ್ಕೇಡಿಂಗ್ ಡಿಲೀಟ್" ನೊಂದಿಗೆ ನಾವು ನವೀಕರಣವನ್ನು ಬಿಡುಗಡೆ ಮಾಡಿದ್ದೇವೆ. ಮತ್ತು ಈಗ ನಾವು _app_start ಮೆಟ್ರಿಕ್ ಮೂಲಕ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಸಮಯವನ್ನು ನಮ್ಮ ನಿರ್ಧಾರವು ಹೇಗೆ ಪ್ರಭಾವಿಸಿದೆ ಎಂಬುದನ್ನು ನಾವು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತೇವೆ ಮತ್ತು ಮೌಲ್ಯಮಾಪನ ಮಾಡುತ್ತೇವೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ವಿಶ್ಲೇಷಣೆಗಾಗಿ, ನಾವು 90 ದಿನಗಳ ಅವಧಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತೇವೆ ಮತ್ತು ನೋಡಿ: ಅಪ್ಲಿಕೇಶನ್ ಉಡಾವಣಾ ಸಮಯ, ಸರಾಸರಿ ಮತ್ತು 95 ನೇ ಶೇಕಡಾ ಬಳಕೆದಾರರ ಮೇಲೆ ಬೀಳುತ್ತದೆ, ಅದು ಕಡಿಮೆಯಾಗಲು ಪ್ರಾರಂಭಿಸಿತು ಮತ್ತು ಇನ್ನು ಮುಂದೆ ಏರಿಕೆಯಾಗುವುದಿಲ್ಲ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯು ಸುದೀರ್ಘ ಉಡಾವಣೆಯಲ್ಲಿ ಹೇಗೆ ಗೆದ್ದಿತು ಎಂಬ ಕಥೆ

ನೀವು ಏಳು-ದಿನದ ಚಾರ್ಟ್ ಅನ್ನು ನೋಡಿದರೆ, _app_start ಮೆಟ್ರಿಕ್ ಸಂಪೂರ್ಣವಾಗಿ ಸಮರ್ಪಕವಾಗಿ ಕಾಣುತ್ತದೆ ಮತ್ತು 1 ಸೆಕೆಂಡ್‌ಗಿಂತ ಕಡಿಮೆಯಿದೆ.

_app_start ನ ಸರಾಸರಿ ಮೌಲ್ಯವು 5 ಸೆಕೆಂಡುಗಳನ್ನು ಮೀರಿದರೆ ಡೀಫಾಲ್ಟ್ ಆಗಿ, Firebase ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸುತ್ತದೆ ಎಂದು ಸೇರಿಸುವುದು ಯೋಗ್ಯವಾಗಿದೆ. ಆದಾಗ್ಯೂ, ನಾವು ನೋಡುವಂತೆ, ನೀವು ಇದನ್ನು ಅವಲಂಬಿಸಬಾರದು, ಬದಲಿಗೆ ಒಳಗೆ ಹೋಗಿ ಅದನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಪರಿಶೀಲಿಸಿ.

Realm ಡೇಟಾಬೇಸ್‌ನ ವಿಶೇಷ ವಿಷಯವೆಂದರೆ ಅದು ಸಂಬಂಧವಿಲ್ಲದ ಡೇಟಾಬೇಸ್ ಆಗಿದೆ. ಅದರ ಬಳಕೆಯ ಸುಲಭತೆಯ ಹೊರತಾಗಿಯೂ, ORM ಪರಿಹಾರಗಳು ಮತ್ತು ಆಬ್ಜೆಕ್ಟ್ ಲಿಂಕ್ ಮಾಡುವ ಹೋಲಿಕೆ, ಇದು ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿಲ್ಲ.

ಇದನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಳ್ಳದಿದ್ದರೆ, ನೆಸ್ಟೆಡ್ ವಸ್ತುಗಳು ಸಂಗ್ರಹವಾಗುತ್ತವೆ ಮತ್ತು "ಸೋರಿಕೆಯಾಗುತ್ತವೆ." ಡೇಟಾಬೇಸ್ ನಿರಂತರವಾಗಿ ಬೆಳೆಯುತ್ತದೆ, ಇದು ಅಪ್ಲಿಕೇಶನ್‌ನ ನಿಧಾನಗತಿ ಅಥವಾ ಪ್ರಾರಂಭದ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ.

ರಿಯಲ್ಮ್‌ನಲ್ಲಿನ ವಸ್ತುಗಳ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯನ್ನು ತ್ವರಿತವಾಗಿ ಹೇಗೆ ಮಾಡುವುದು ಎಂಬುದರ ಕುರಿತು ನಾನು ನಮ್ಮ ಅನುಭವವನ್ನು ಹಂಚಿಕೊಂಡಿದ್ದೇನೆ, ಅದು ಇನ್ನೂ ಬಾಕ್ಸ್‌ನಿಂದ ಹೊರಗಿಲ್ಲ, ಆದರೆ ದೀರ್ಘಕಾಲದವರೆಗೆ ಮಾತನಾಡಲಾಗಿದೆ ಅವರು ಹೇಳುತ್ತಾರೆ и ಅವರು ಹೇಳುತ್ತಾರೆ. ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ, ಇದು ಅಪ್ಲಿಕೇಶನ್ ಪ್ರಾರಂಭದ ಸಮಯವನ್ನು ಹೆಚ್ಚು ವೇಗಗೊಳಿಸುತ್ತದೆ.

ಈ ವೈಶಿಷ್ಟ್ಯದ ಸನ್ನಿಹಿತ ಗೋಚರಿಸುವಿಕೆಯ ಬಗ್ಗೆ ಚರ್ಚೆಯ ಹೊರತಾಗಿಯೂ, ರಿಯಲ್ಮ್ನಲ್ಲಿ ಕ್ಯಾಸ್ಕೇಡ್ ಅಳಿಸುವಿಕೆಯ ಅನುಪಸ್ಥಿತಿಯು ವಿನ್ಯಾಸದಿಂದ ಮಾಡಲ್ಪಟ್ಟಿದೆ. ನೀವು ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸುತ್ತಿದ್ದರೆ, ಇದನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಳ್ಳಿ. ಮತ್ತು ನೀವು ಈಗಾಗಲೇ ರಿಯಲ್ಮ್ ಅನ್ನು ಬಳಸುತ್ತಿದ್ದರೆ, ನೀವು ಅಂತಹ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದ್ದರೆ ಪರಿಶೀಲಿಸಿ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ