Khi làm việc trên một dự án nhạy cảm thời gian, tôi đã sử dụng mã bên dưới để kiểm tra độ chi tiết của các sự kiện thời gian có sẵn, trước tiên trên máy tính để bàn của tôi trong Firefox, sau đó là mã node.js trên máy chủ Linux của tôi. Chạy Firefox tạo ra kết quả dự đoán được, trung bình 200 khung hình/giây trên thời gian chờ 1ms và cho biết tôi có các sự kiện thời gian với độ chi tiết 5ms.Tại sao node.js xử lý setTimeout (func, 1.0) không chính xác?
Bây giờ tôi biết rằng nếu tôi đã sử dụng giá trị thời gian chờ là 0, công cụ Node.js của Chrome V8 được xây dựng trên thực tế sẽ không ủy thác thời gian chờ cho sự kiện nhưng xử lý ngay lập tức. Theo dự kiến, các con số trung bình 60.000 khung hình/giây, xử lý rõ ràng liên tục ở công suất CPU (và được xác minh bằng đầu). Nhưng với thời gian chờ 1ms, các con số vẫn còn khoảng 3,5-4 nghìn chu kỳ() mỗi giây, có nghĩa là Node.js không thể tôn trọng thời gian chờ 1ms mà sẽ tạo ra tối đa lý thuyết là 1 nghìn chu kỳ() mỗi giây.
Chơi với một loạt các con số, tôi nhận được:
- 2ms: ~ 100 fps (timeout đúng, cho thấy 10ms granularity của thời gian sự kiện trên Linux)
- 1.5: cùng
- 1,0001: cùng
- 1.0: 3.500 - 4.500 fps
- 0.99: 2.800 - 3.600 fps
- 0,5: 1.100 - 2.800 fps
- 0,0001: 1.800 - 3.300 fps
- 0.0: ~ 60.000 fps
Hành vi của setTimeout (func, 0) dường như có thể tha thứ, bởi vì đặc tả ECMAScript có lẽ làm cho không có lời hứa của setTimout ủy thác cuộc gọi đến một thực tế Ngắt cấp hệ điều hành. Nhưng kết quả cho bất cứ điều gì 0 < x < = 1.0 rõ ràng là vô lý. Tôi đã cho một khoảng thời gian rõ ràng để trì hoãn, và thời gian tối thiểu lý thuyết cho n cuộc gọi trên x chậm trễ nên được (n-1) * x. V8/Node.js đang hoạt động như thế nào?
var timer, counter = 0, time = new Date().getTime();
function cycle() {
counter++;
var curT = new Date().getTime();
if(curT - time > 1000) {
console.log(counter+" fps");
time += 1000;
counter = 0;
}
timer = setTimeout(cycle, 1);
}
function stop() {
clearTimeout(timer);
}
setTimeout(stop, 10000);
cycle();
gì tôi đoán là đội Node.js quan sát mã trong môi trường tự nhiên được sử dụng '1' như một giá trị thời gian chờ để có nghĩa là 'càng sớm càng tốt'. Tôi biết nhiều lập trình viên (bao gồm cả bản thân mình) ngần ngại viết 'setTimeout (someFunc, 0) 'vì' 0' bằng cách nào đó' cảm thấy sai 'ở đây ... Một thời gian chờ bằng 0 không có thời gian chờ. '1' có vẻ là giá trị logic tiếp theo có nghĩa là ASAP trong mã như vậy. Vì vậy, mã Node.js có lẽ chỉ có một kiểm tra như 'if (timeout> 1) {scheduleTimeout (someFunc, timeout);} else {scheduleNextTick (someFunc);}' –
Câu hỏi rất thú vị BTW. Tôi thích loại nghiên cứu này! –