c# - Azure 云服务的 for 循环在生产环境中比在本地主机上慢得多

标签 c# performance azure asp.net-web-api azure-cloud-services

出于某种原因,这段特定的代码在生产服务器(XL Azure 云服务)上的运行速度比在本地主机上慢得多。最糟糕的是,这种缓慢程度并不一致,即大多数时候很慢,但有时却很快。我所说的“慢”是指这段代码在生产环境中运行需要 4.000 毫秒(我知道这一点是因为我使用的是 Azure AppInsights),而在本地主机上只需要大约 60 毫秒。我不明白为什么会发生这种情况。这是代码(请注意,这只是更大方法的一部分,但我确信这部分是最慢的,其他一切都快得多):

for (var i = 0; i < feedDeserialized.Length; i++)
{
RedisWorkoutItem workout;
bool hasRespected;
string username, fullName, profilePic;

// usersFromRedis is  an array of Dictonary <string,string>
var userRedis = usersFromRedis[i];
// workoutsFromRedis is just an array of objects - RedisValue object
var stringWorkout = workoutsFromRedis[i];
// just an array of objects - RedisValue object
var workoutComment = commentsFromRedis[i].HasValue ? commentsFromRedis[i].ToString() : "";

if (userRedis != null)
{
    profilePic = userRedis["ProfilePhotoUrl"].HasValue
        ? userRedis["ProfilePhotoUrl"].ToString()
        : "";
    fullName = userRedis["FirstName"] + " " + userRedis["LastName"];
    username = userRedis["UserName"].HasValue ? userRedis["UserName"].ToString() : "";
}
//code inside this else statement never happens
else
{
    var stopWatch2 = new Stopwatch();
    stopWatch2.Start();
    var user = databaseContext.Users.Find(feedDeserialized[i].UserId);
    profilePic = user.ProfilePhotoUrl;
    username = user.UserName;
    fullName = user.FirstName + " " + user.LastName;
    stopWatch2.Stop();
    telemetryHelper.TrackEvent(_telemetryClient,
        "CreateRedisFeedViewModelAsync: Went to DB for user", stopWatch2.Elapsed);
}

if (stringWorkout.HasValue)
{
    workout = JsonConvert.DeserializeObject<RedisWorkoutItem>(stringWorkout);
    hasRespected = workout.UsersWhoRespected.Contains(userId);
}
//code inside this else statement never happens
else
{
    var stopWatch2 = new Stopwatch();
    stopWatch2.Start();
    var workoutGuid = Guid.Parse(feedDeserialized[i].WorkoutId);

    var workoutFromDb = await databaseContext.Trenings.FindAsync(workoutGuid);
    var routine = await databaseContext.AllRoutineses.FindAsync(workoutFromDb.AllRoutinesId);
    workout = new RedisWorkoutItem
    {
        Name = routine.Name,
        Id = workoutFromDb.TreningId.ToString(),
        Comment = workoutFromDb.UsersCommentOnWorkout,
        DateWhenFinished = workoutFromDb.DateTimeWhenTreningCreated,
        NumberOfRespects = workoutFromDb.NumberOfLikes,
        NumberOfComments = workoutFromDb.NumberOfComments,
        UserId = workoutFromDb.UserId,
        Length = workoutFromDb.LengthInSeconds,
        Points = workoutFromDb.Score
    };

    workoutComment = workoutFromDb.UsersCommentOnWorkout;


    hasRespected = databaseContext.TreningRespects
        .FirstOrDefault(r => r.TreningId == workoutGuid && r.UserId == userId) != null;

    stopWatch2.Stop();
    telemetryHelper.TrackEvent(_telemetryClient,
        "CreateRedisFeedViewModelAsync: Went to DB for workout", stopWatch2.Elapsed);
}

string workoutLength;

if (workout.Length >= 3600)
{
    var t = TimeSpan.FromSeconds(workout.Length);
    workoutLength = $"{t.Hours:D2}:{t.Minutes:D2}:{t.Seconds:D2}";
}
else
{
    var t = TimeSpan.FromSeconds(workout.Length);
    workoutLength = $"{t.Minutes:D2}:{t.Seconds:D2}";
}


listToReturn.Add(new FeedMobileHelper
{
    Id = feedDeserialized[i].Id.ToString(),
    UserId = workout.UserId,
    WorkoutId = feedDeserialized[i].WorkoutId,
    Points = workout.Points.ToString("N0", new NumberFormatInfo
    {
        NumberGroupSizes = new[] {3},
        NumberGroupSeparator = "."
    }),
    WorkoutName = workout.Name,
    WorkoutLength = workoutLength,
    NumberOfRespects = workout.NumberOfRespects,
    NumberOfComments = workout.NumberOfComments,
    WorkoutComment = workoutComment,
    HasRespected = hasRespected,
    UserImageUrl = profilePic,
    UserName = username,
    DisplayName = string.IsNullOrWhiteSpace(fullName) ? username : fullName,
    TimeStamp = workout.DateWhenFinished,
    DateFormatted = workout.DateWhenFinished.FormatDateToHrsDaysWeeksString()
});
}

我无法理解为什么这需要 4 秒才能在具有 8 个核心和 15 GB RAM 的云服务上完成,特别是因为这里没有什么花哨的东西,没有访问数据库(正如我在评论中指出的“其他部分”)代码永远不会被执行)或光盘,一切都在内存中完成。循环中的大部分事情都是在恒定时间内完成的 - O(1)。请任何人都可以帮我弄清楚这里出了什么问题。

还有一件事,执行这部分代码的 API 调用不会同时被数千个用户调用,它只由我调用(我确信这一点)。

附注

feedDeserialized.长度约为60

最佳答案

第一个想法 - 您是将调试版本还是发布版本部署到 Azure 云服务?发布版本经过优化并且速度更快。如果右键单击您的云服务并选择Publish...,您可以选择要部署的版本。此外,您可能希望启用分析(在高级设置下作为发布向导的一部分)以查看应用程序的缓慢部分。

关于c# - Azure 云服务的 for 循环在生产环境中比在本地主机上慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35344830/

相关文章:

sql - sql 2008中大表的高效分页

sql-server - 我可以在一组 Azure 服务器上运行 .bat 文件吗?

c# - 在 Azure Eventhub 中发布数据时出现未经授权的错误

c# - Order By 与条件的关系的子集

c# - 从 Sync 方法调用 Async 方法的最佳做法是什么?

c# - 如何在 datagridview 中存储每个用户/行的复选框数据,使其保持一致?

javascript - 如何在C#代码后面编写Javascript代码?

java - 分片后MongoDB插入速度变慢

php - 如何提高十亿行表的插入性能?

java - 插入数据, "MobileServiceTable must have a single id property defined"