3
\$\begingroup\$

I have the following async ActionResult.

public async Task<ActionResult> most_loved_pix()
{

    var access_token = HttpContext.Items["access_token"].ToString();
    if (!string.IsNullOrEmpty(access_token))
    {
        Account account = new Account();
        account.Cloud = ConfigurationManager.AppSettings["CloudName"];
        account.ApiKey = ConfigurationManager.AppSettings["CloudinaryAPI"];
        account.ApiSecret = ConfigurationManager.AppSettings["CloudinarySecret"];

        Cloudinary cloudinary = new Cloudinary(account);

        var appsecret_proof = access_token.GenerateAppSecretProof();

        var fb = new FacebookClient(access_token);

        #region FacebookUser Name and Picture plus other Info
        //Get current user's profile
        dynamic myInfo = await fb.GetTaskAsync("me?fields=id,first_name,last_name,link,locale,email,name,birthday,gender,location,age_range,about".GraphAPICall(appsecret_proof));

        dynamic myinfojson = JsonConvert.DeserializeObject(myInfo.ToString());

        string userName = myinfojson.name;
        string userId = myinfojson.id;
        string firstName = myinfojson.first_name;

        //get current picture
        dynamic profileImgResult = await fb.GetTaskAsync("{0}/picture?width=200&height=200&redirect=false".GraphAPICall((string)myInfo.id, appsecret_proof));

        ViewBag.ProfilePictureURL = profileImgResult.data.url;
        #endregion

        dynamic myAlbums = await fb.GetTaskAsync(
                ("me/albums?fields = id,name")
                .GraphAPICall(appsecret_proof));
        string result = myAlbums.ToString();


        var jsonResult = JsonConvert.DeserializeObject<AlbumsRootObject>(result);
        if (jsonResult.data.Count < 1)
        {
            return RedirectToAction("Index", "Home");
        }

        foreach (var AlbumItems in jsonResult.data.Where(i => i.name == "Profile Pictures"))
        {

            string albumIdstring = AlbumItems.id.ToString();

            string AlbumId = albumIdstring.Trim('"');

            dynamic myProfilePictures = await fb.GetTaskAsync(
                (string.Format("{0}/photos", AlbumId)
                + "?fields=images,likes.summary(total_count),comments.summary(total_count),reactions.type(LOVE).summary(true)&limit=10")
                .GraphAPICall(appsecret_proof));

            string pictures = myProfilePictures.ToString();

            var picturesResult = JsonConvert.DeserializeObject<ProfilePicturesRootObject>(pictures);

            #region MostLiked
            var likesSummary = new List<ProfilePicturesSummary>();
            var likesImages = new List<ProfilePicturesImage>();

            foreach (var LikesItems in picturesResult.data)
            {
                likesSummary.Add(LikesItems.likes.summary);
                foreach (var imagesLiked in LikesItems.images)
                {
                    likesImages.Add(imagesLiked);
                    break;
                }
            }
            var maxLikeCount = likesSummary.Max( l => l.total_count);

            var maxlikecountindex = likesSummary.FindIndex(a => a.total_count == maxLikeCount);

            var imageindex = likesImages[maxlikecountindex];

            string mostlikedImageSourceRawURL = imageindex.source.ToString();

            string mostlikedImageSourceTrimedURL = mostlikedImageSourceRawURL.Trim('"');

            if (!string.IsNullOrEmpty(mostlikedImageSourceRawURL))
            {
                var UsersMostLikedtextParams = new TextParams("دوست داشتنی")
                {
                    PublicId = string.Format("MostLiked{0}", userId),
                    FontFamily = "Amiri",
                    //FontWeight = "regular",
                    FontSize = 40,
                    TextAlign = "center",
                    FontColor = "blue",
                    Background = "white",
                    Opacity = "60"
                };
                var textResult = cloudinary.Text(UsersMostLikedtextParams);

                var usersMostLikedImage = new ImageUploadParams()
                {
                    File = new FileDescription(mostlikedImageSourceTrimedURL),
                    PublicId = string.Format("MostLiked{0}", AlbumId),
                    Tags = "Most Liked Picture, Facebook",
                    Transformation = new Transformation().Border("1px_solid_blue")
                    .Width(233).Height(320).Crop("fill")
                    .Chain().Overlay("like.png").Flags("relative").Gravity("north_east").Width(65).Height(65)
                    .Chain().Overlay(string.Format("text:MostLiked{0}.png", userId)).Radius(20).Gravity("south").Y(20)
                };
                var userMostLikedImageResult = cloudinary.Upload(usersMostLikedImage);
            }

            #endregion

            #region MostLoved

            var mostCommentedImageCommentCount = new List<ProfilePicturesSummary2>();
            var mostCommentedImageSource = new List<ProfilePicturesImage>();

            foreach (var CommentItems in picturesResult.data)
            {
                mostCommentedImageCommentCount.Add(CommentItems.comments.summary);
                foreach (var imageCommented in CommentItems.images)
                {
                    mostCommentedImageSource.Add(imageCommented);
                    break;
                }
            }

            var mostCommentCount = mostCommentedImageCommentCount.Max(l => l.total_count);

            var mostCommentCountIndex = mostCommentedImageCommentCount.FindIndex(a => a.total_count == mostCommentCount);
            var commentImageIndex = mostCommentedImageSource[mostCommentCountIndex];

            string mostCommentedImageRawURL = commentImageIndex.source.ToString();
            string mostCommentedImageTrimmedURL = mostCommentedImageRawURL.Trim('"');

            if (!string.IsNullOrEmpty(mostCommentedImageRawURL))
            {
                var UsersMostLovedtextParams = new TextParams("دلپذیر")
                {
                    PublicId = string.Format("MostLoved{0}", userId),
                    FontFamily = "Amiri",
                    //FontWeight = "regular",
                    FontSize = 40,
                    TextAlign = "center",
                    FontColor = "red",
                    Background = "white",
                    Opacity = "60"
                };
                var UserMostLovedtextResult = cloudinary.Text(UsersMostLovedtextParams);
                var usersMostLovedImage = new ImageUploadParams()
                {
                    File = new FileDescription(mostCommentedImageTrimmedURL),
                    PublicId = string.Format("MostLoved{0}", AlbumId),
                    Tags = "Most Commented, Facebook",
                    Transformation = new Transformation().Border("1px_solid_red")
                    .Width(233).Height(320).Crop("fill")
                    .Chain().Overlay("love.png").Flags("relative").Gravity("north_east").Width(65).Height(65)
                    .Chain().Overlay(string.Format("text:MostLoved{0}.png", userId)).Radius(20).Gravity("south").Y(20)
                };

                var usersMostLovedImageResult = cloudinary.Upload(usersMostLovedImage);
            }

            #endregion

            #region MostCommented
            var mostLovedImageCommentCount = new List<ProfilePicturesSummary3>();
            var mostLovedImageSource = new List<ProfilePicturesImage>();

            foreach (var Loved in picturesResult.data)
            {
                mostLovedImageCommentCount.Add(Loved.reactions.summary);
                foreach (var imageLoved in Loved.images)
                {
                    mostLovedImageSource.Add(imageLoved);
                    break;
                }
            }

            var mostLovedCount = mostLovedImageCommentCount.Max(l => l.total_count);

            var mostLovedCountIndex = mostLovedImageCommentCount.FindIndex(a => a.total_count == mostLovedCount);

            var lovedImageIndex = mostLovedImageSource[mostLovedCountIndex];

            string mostLovedImageRawURL = lovedImageIndex.source.ToString();

            string mostLovedImageTrimmedURL = mostLovedImageRawURL.Trim('"');

            if (!string.IsNullOrEmpty(mostLovedImageRawURL))
            {
                var UsersMostCommentedtextParams = new TextParams("بیشترین اظهار نظرات")
                {
                    PublicId = string.Format("MostComment{0}", userId),
                    FontFamily = "Amiri",
                    //FontWeight = "regular",
                    FontSize = 30,
                    TextAlign = "center",
                    FontColor = "green",
                    Background = "white",
                    Opacity = "60"
                };
                var UserMostCommentedtextResult = cloudinary.Text(UsersMostCommentedtextParams);

                var mostCommentImage = new ImageUploadParams()
                {
                    File = new FileDescription(mostLovedImageTrimmedURL),
                    PublicId = string.Format("MostComment{0}", AlbumId),
                    Tags = "Most Comment, Facebook",
                    Transformation = new Transformation().Border("1px_solid_green")
                    .Width(233).Height(320).Crop("fill")
                    .Chain().Overlay("comment.png").Flags("relative").Gravity("north_east").Width(65).Height(65)
                    .Chain().Overlay(string.Format("text:MostComment{0}.png", userId)).Radius(20).Gravity("south").Y(20)
                };
                var mostCommentImageResult = cloudinary.Upload(mostCommentImage);
            }

            #endregion

            #region BuildImageFinalURL

                ViewBag.ImageURL = cloudinary.Api.UrlImgUp.Transform(new Transformation()
                        .Width(233).Height(320).Overlay(string.Format("MostLiked{0}.jpg", AlbumId)).Gravity("north_west").Y(50).X(0)
                        .Chain().Width(233).Height(320).Overlay(string.Format("MostLoved{0}.jpg", AlbumId)).Gravity("north").Y(50).X(0)
                        .Chain().Width(233).Height(320).Overlay(string.Format("MostComment{0}.jpg", AlbumId)).Gravity("north_east").Y(50).X(0))
                        .BuildUrl("top_three.jpg");
            return View();

            #endregion
        }


    }
    return View();
}

As you can see above piece of code does some API Calls to retrieve Json formatted data and then serialize it also does some API calls to Cloudinary for manipulation or image upload. I tested this action with Glimps profiling tool and apparently it took 34k+ ms to execute the result. I would like to bring it down to 5k ms. Is it possible?

I cannot reply to any of the comments below as my reputation is under 50.

\$\endgroup\$
3
  • \$\begingroup\$ This method is huge. If you tested it with a profiler, it should have told you which parts are the slowest ones, haven't it? \$\endgroup\$
    – t3chb0t
    Commented Feb 15, 2017 at 19:58
  • \$\begingroup\$ Without more specific profiling it is hard to say for sure, but I woud try to parallelize the AlbumItems-foreach. \$\endgroup\$
    – Hekku2
    Commented Feb 16, 2017 at 20:29
  • \$\begingroup\$ Your use of dynamic will not help your case, you should build POCO's for any deserialization, \$\endgroup\$ Commented Feb 17, 2017 at 16:33

2 Answers 2

1
\$\begingroup\$

Using region's is discussed contraversial but using regions inside a method is a clear sign that the method should be broken into multiple methods.

It is screaming loudly "Violation of single responsibility principle"!

\$\endgroup\$
1
\$\begingroup\$

It's very hard to tell you what needs to be improved. This method does a lot and you'll need to norrow down the performance bottleneck to something more specific. In order to do this you have the following options:

  • Measure each feature of this method with the Stopwatch (you really shouldn't do it - but, it's an option).
  • Run this code with a profiler - it'll tell you what slows it down.
  • Refactor this method into smaller pieces that you can better measure/profile and then optimize (this is the preferred option).

I tested this action with Glimps profiling tool and apparently it took 34k+ ms to execute the result. I would like to bring it down to 5k ms. Is it possible?

Probably no body can tell you this. You perform some web-requests. If they need several seconds to complete there's hardly anything that can be done about them. Maybe you try to get too much data or you internet connection is slow? Who knows. Measure it first.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.