改进循环中的…以更快地使用Typescript
所以我被要求改进一个使用typescript中“for…in”的代码,以提高速度 这是原始代码:改进循环中的…以更快地使用Typescript,typescript,for-loop,asynchronous,Typescript,For Loop,Asynchronous,所以我被要求改进一个使用typescript中“for…in”的代码,以提高速度 这是原始代码: export interface AddressBook { emp_id: string | null; first: string; last: string; email: string; } export interface Payroll { emp_id: string; vacationDays: number; } interf
export interface AddressBook {
emp_id: string | null;
first: string;
last: string;
email: string;
}
export interface Payroll {
emp_id: string;
vacationDays: number;
}
interface Employee {
id: string;
name: string;
startDate: Date;
endDate: Date | null;
}
export interface EmailApi {
sendEmail(email: string, subject: string, body: string): void;
}
function yearsSince(startDate: Date, endDate: Date): number {
const millisecondsPerYear = 365 * 24 * 60 * 60 * 1000;
return Math.trunc((endDate.getTime() - startDate.getTime()) / millisecondsPerYear);
}
/**
* We haved decided to grant bonus vacation to every employee, 1 day per year of experience
* we need to email them a notice.
*/
function grantVacation(
emailApi: EmailApi,
payroll: Payroll[],
addresses: AddressBook[],
employees: Employee[],
) {
for (var index in payroll) {
let payrollInfo = payroll[index];
let addressInfo = addresses.find(x => x.emp_id == payrollInfo.emp_id);
let empInfo = employees.find(x => x.id == payrollInfo.emp_id);
let today = new Date();
let yearsEmployed = 0;
if (empInfo != undefined) {
yearsEmployed = yearsSince(empInfo.startDate, today);
}
let newVacationBalance = yearsEmployed + payrollInfo.vacationDays;
if (addressInfo != undefined && empInfo != undefined) {
emailApi.sendEmail(
addressInfo.email,
"Good news!",
`Dear ${empInfo.name}\n` +
`based on your ${yearsEmployed} years of employment, you have been granted ${yearsEmployed} days of vacation, bringing your total to ${newVacationBalance}`
);
}
}
console.timeEnd();
}
// for the testing part I'll implement sendEmail as printing:
class myEmailApi implements EmailApi {
sendEmail(email: string, subject: string, body: string): void {
console.log('********************');
console.log(`To ${email}, Subject: ${subject}, body: ${body}`);
console.log('********************');
}
}
let myPayroll: Payroll[] = [
{ emp_id: "1", vacationDays: 1 },
{ emp_id: "2", vacationDays: 2 },
{ emp_id: "3", vacationDays: 3 },
{ emp_id: "4", vacationDays: 4 },
{ emp_id: "5", vacationDays: 5 },
{ emp_id: "6", vacationDays: 6 }
];
let myAdress: AddressBook[] = [
{ emp_id: "1", first: "emp", last: "number 1", email: "emp1@gmail.com" },
{ emp_id: "2", first: "emp", last: "number 2", email: "emp2@gmail.com" },
{ emp_id: "3", first: "emp", last: "number 3", email: "emp3@gmail.com" },
{ emp_id: "4", first: "emp", last: "number 4", email: "emp4@gmail.com" },
{ emp_id: "5", first: "emp", last: "number 5", email: "emp5@gmail.com" },
{ emp_id: "6", first: "emp", last: "number 6", email: "emp6@gmail.com" },
];
let myEmployees: Employee[] = [
{ id: "1", name: "emp number 1", startDate: new Date("2020-01-01"), endDate: new Date("2025-01-01") },
{ id: "2", name: "emp number 2", startDate: new Date("2019-01-01"), endDate: new Date("2025-01-01") },
{ id: "3", name: "emp number 3", startDate: new Date("2018-01-01"), endDate: new Date("2025-01-01") },
{ id: "4", name: "emp number 4", startDate: new Date("2017-01-01"), endDate: new Date("2025-01-01") },
{ id: "5", name: "emp number 5", startDate: new Date("2016-01-01"), endDate: new Date("2025-01-01") },
{ id: "6", name: "emp number 6", startDate: new Date("2015-01-01"), endDate: new Date("2025-01-01") },
];
grantVacation(new myEmailApi(), myPayroll, myAdress, myEmployees);
这里没有什么特别的,这是一个演示,用于在计算员工的新假期后向公司的每位员工发送电子邮件
所以我已经读到,与其他循环(while、for、foreach)相比,使用“for…in”的速度非常慢,不应该使用,因为它对每个属性都使用了查找机制,这使得代码非常慢
我试图像这样改进代码(使用异步),但当我测量时间时,我发现两个版本有些相同,甚至更糟,这意味着我的解决方案至少没有提高性能
我的代码的改进版本是:
export interface AddressBook {
emp_id: string | null;
first: string;
last: string;
email: string;
}
export interface Payroll {
emp_id: string;
vacationDays: number;
}
interface Employee {
id: string;
name: string;
startDate: Date;
endDate: Date | null;
}
export interface EmailApi {
sendEmail(email: string, subject: string, body: string): void;
}
function yearsSince(startDate: Date, endDate: Date): number {
const millisecondsPerYear = 365 * 24 * 60 * 60 * 1000;
return Math.trunc((endDate.getTime() - startDate.getTime()) / millisecondsPerYear);
}
/**
* We haved decided to grant bonus vacation to every employee, 1 day per year of experience
* we need to email them a notice.
*/
function calculateVacation(payrollInfo: Payroll, empInfo: Employee): Promise<any> {
// "wrap" a sync function inside of a promise and finish the calulation.
return new Promise((resolve) => {
let today = new Date();
let yearsEmployed = 0;
if (empInfo != undefined) {
yearsEmployed = yearsSince(empInfo.startDate, today);
}
let newVacationBalance = yearsEmployed + payrollInfo.vacationDays;
// return all the relevant values from this promise as a single array to use.
resolve([empInfo?.name, yearsEmployed, newVacationBalance]);
});
}
async function asyncSendEmail(emailApi: EmailApi, payrollInfo: Payroll, addresses: AddressBook[], employees: Employee[]) {
//Moran's note: adding a timer to see the performance.
const startTime = Date.now();
let addressInfo = addresses.find(x => x.emp_id == payrollInfo.emp_id);
await Promise.all(employees.map(empInfo => {
if (empInfo.id == payrollInfo.emp_id) {
calculateVacation(payrollInfo, empInfo)
.then(([empInfoName, yearsEmployed, newVacationBalance]) => {
if (addressInfo != undefined) {
emailApi.sendEmail(
addressInfo.email,
"Good news!",
`Dear ${empInfoName}\n` +
`based on your ${yearsEmployed} years of employment, you have been granted ${yearsEmployed} days of vacation, bringing your total to ${newVacationBalance}`
);
}
});
}
}));
const msElapsed = Date.now() - startTime;
console.log(`Async function took ${msElapsed} ms to complete.`);
}
function grantVacation(
emailApi: EmailApi,
payroll: Payroll[],
addresses: AddressBook[],
employees: Employee[]) {
for (let i = 0; i < payroll.length; i++) {
let payrollInfo = payroll[i];
asyncSendEmail(emailApi, payrollInfo, addresses, employees);
}
}
// for the testing part I'll implement sendEmail as printing:
class myEmailApi implements EmailApi {
sendEmail(email: string, subject: string, body: string): void {
console.log('********************');
console.log(`To ${email}, Subject: ${subject}, body: ${body}`);
console.log('********************');
}
}
let myPayroll: Payroll[] = [
{ emp_id: "1", vacationDays: 1 },
{ emp_id: "2", vacationDays: 2 },
{ emp_id: "3", vacationDays: 3 },
{ emp_id: "4", vacationDays: 4 },
{ emp_id: "5", vacationDays: 5 },
{ emp_id: "6", vacationDays: 6 }
];
let myAdress: AddressBook[] = [
{ emp_id: "1", first: "emp", last: "number 1", email: "emp1@gmail.com" },
{ emp_id: "2", first: "emp", last: "number 2", email: "emp2@gmail.com" },
{ emp_id: "3", first: "emp", last: "number 3", email: "emp3@gmail.com" },
{ emp_id: "4", first: "emp", last: "number 4", email: "emp4@gmail.com" },
{ emp_id: "5", first: "emp", last: "number 5", email: "emp5@gmail.com" },
{ emp_id: "6", first: "emp", last: "number 6", email: "emp6@gmail.com" },
];
let myEmployees: Employee[] = [
{ id: "1", name: "emp number 1", startDate: new Date("2020-01-01"), endDate: new Date("2025-01-01") },
{ id: "2", name: "emp number 2", startDate: new Date("2019-01-01"), endDate: new Date("2025-01-01") },
{ id: "3", name: "emp number 3", startDate: new Date("2018-01-01"), endDate: new Date("2025-01-01") },
{ id: "4", name: "emp number 4", startDate: new Date("2017-01-01"), endDate: new Date("2025-01-01") },
{ id: "5", name: "emp number 5", startDate: new Date("2016-01-01"), endDate: new Date("2025-01-01") },
{ id: "6", name: "emp number 6", startDate: new Date("2015-01-01"), endDate: new Date("2025-01-01") },
];
grantVacation(new myEmailApi(), myPayroll, myAdress, myEmployees);
导出接口地址簿{
emp_id:string | null;
第一:字符串;
最后:字符串;
电子邮件:字符串;
}
出口接口工资单{
emp_id:string;
假期天数:天数;
}
接口员工{
id:字符串;
名称:字符串;
起始日期:日期;
endDate:日期|空;
}
导出接口EmailApi{
sendmail(email:string,subject:string,body:string):void;
}
功能年份(开始日期:日期,结束日期:日期):编号{
常数毫秒每秒=365*24*60*60*1000;
返回Math.trunc((endDate.getTime()-startDate.getTime())/millissecondsperyear);
}
/**
*我们已经决定给每位员工发放奖金假期,每年工作一天
*我们需要给他们发邮件通知。
*/
功能计算评估(payrollInfo:Payroll,empInfo:Employee):承诺{
//将同步函数“包装”在承诺中并完成计算。
返回新承诺((解决)=>{
让今天=新日期();
设yearsEmployed=0;
如果(empInfo!=未定义){
yearsEmployed=yearsSince(empInfo.startDate,今天);
}
让newVacationBalance=yearsEmployed+payrollInfo.vacationDays;
//将此承诺中的所有相关值作为单个数组返回以供使用。
解析([empInfo?.name,部署年份,newVacationBalance]);
});
}
异步函数asyncSendEmail(emailApi:emailApi,payrollInfo:Payroll,地址:通讯簿[],员工:员工[]){
//莫兰注:添加计时器以查看性能。
const startTime=Date.now();
让addressInfo=addresses.find(x=>x.emp\u id==payrollInfo.emp\u id);
等待承诺.all(employees.map)(empInfo=>{
如果(empInfo.id==payrollInfo.emp_id){
计算评估(工资汇总信息、empInfo)
.然后(([empInfoName,yearsEmployed,newVacationBalance])=>{
如果(地址信息!=未定义){
emailApi.sendmail(
addressInfo.email,
“好消息!”,
`亲爱的${empInfoName}\n`+
`根据您${yearsememployed}年的工作年限,您已获得${yearsEmployed}天的假期,使您的总假期达到${newVacationBalance}`
);
}
});
}
}));
const msepersed=Date.now()-startTime;
log(`Async函数需要${msepersed}毫秒才能完成。`);
}
功能颗粒(
emailApi:emailApi,
工资总额:工资总额[],
地址:通讯簿[],
员工:员工[]){
for(设i=0;i
我真的很想知道我做错了什么?也许我的异步实现方式遗漏了一些基本知识?
也许代码是可以的,但是当测量给定测试数据的时间(我可以使其大于6)时,是不是太小了
提前谢谢