I wrote the code that reads bulks of data from Redis and writes those bulks to SQL Server using async await in C#.
I have written the following code in my TeamController
class using async/await to make reading from REDIS in parallel with writing to SQL Server:
[Route("api/[controller]")]
[ApiController]
public class TeamController : ControllerBase
{
private ICacheManager cacheManager;
private IDBManager dbManager;
private IDomainDataConverter _domainDataConverter;
public TeamController(ICacheManager cacheManager,
IDBManager dbManager,
IDomainDataConverter domainDataConverter)
{
this.cacheManager = cacheManager;
this.dbManager = dbManager;
this._domainDataConverter = domainDataConverter;
}
[HttpPost, Route("SaveDataParallel")]
public async Task<IActionResult> SaveDataParallel(int parallelDegree, int totalCount)
{
int chunkeSize = totalCount / parallelDegree;
int remainder = totalCount - chunkeSize * parallelDegree;
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
try
{
var tasks = new List<Task>();
for (int i = 0; i < parallelDegree; i++)
{
tasks.Add(SaveChunkAsync(i, chunkeSize, parallelDegree, remainder));
}
await Task.WhenAll(tasks);
st.Stop();
}
catch
{
}
return Ok(st.ElapsedMilliseconds);
}
[HttpPost, Route("SaveDataSimple")]
public IActionResult SaveDataWithSimple(int parallelDegree, int totalCount)
{
int chunkeSize = totalCount / parallelDegree;
int remainder = totalCount - chunkeSize * parallelDegree;
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
try
{
for (int i = 0; i < parallelDegree; i++)
{
SaveChunk(i, chunkeSize, parallelDegree, remainder);
}
st.Stop();
}
catch (Exception ex)
{
}
return Ok(st.ElapsedMilliseconds);
}
private async Task SaveChunkAsync(int i, int pageSize, int parallelDegree, int remainder)
{
var data = cacheManager.ReadDataAsync<TeamDto>(i * pageSize, (i == parallelDegree - 1 ? remainder : 0) + pageSize);
var arr = _domainDataConverter.Convert<Team, TeamDto>(data.Result);
await dbManager.BulkInsertAsync(arr);
}
private void SaveChunk(int i, int pageSize, int parallelDegree, int remainder)
{
var data = cacheManager.ReadData<TeamDto>(i * pageSize, (i == parallelDegree - 1 ? remainder : 0) + pageSize);
var arr = _domainDataConverter.Convert<Team, TeamDto>(data);
dbManager.BulkInsert(arr);
}
}
I'm comparing the performance of the two methods: SaveDataParallel
and SaveDataWithSimple
. Unfortunately I don't seem to see a significant difference between the two method calls in terms of performance.
If
n = total number of read and writes
td = time required to save chunk of data to SQL,
tr = time required to read chunk of data from Redis,
tparallel = total time for SaveDataParallel,
tsimple = total time for SaveDataWithSimple,
I expect tparallel
to be as follows:
tparallel = (max(td, tr) * n) / 2 + tr
and tsimple
as follows:
tsimple = (max(td, tr)) * n
but the result is different and the two tsimple
and tparallel
values don't appear to have a significant difference.
Does anybody have any idea why? Am I expecting the right thing? Or there is something wrong with the code?
I would appreciate any ideas or guidance.