同样的程序,在高配置服务器上运行时间比本地慢几十秒,求解!

hailan_li 2017-08-01 06:22:01
我写了一段程序,放在C# 内存表进行运算,

A、本地是win7 64 旗舰版,I7 处理器,16GB内存,运行时间只需要36秒,本地还安装很多其他乱七八糟的软件什么的
B、同样的程序,发布到服务器上,运行时间则是96秒,不知道为什么差这么多,服务器是WIN SERVER 2012 64位,4颗CPU,256 GB 内存

服务器里面都没有安装,仅安装这个系统服务,是不是服务器需要某些特殊设置,能让这个系统服务大量使用CPU或内存,目前运行情况来看,CPU不到1%,内存也只占用了一点点!特来求解,谢谢!

是用C#写的一个系统服务(windows service) .net framework 4.5.1

部分代码如下:


public static void INITIAL_DATA_LIST()
{
ANALYSISES.DATA_LIST = new DataTable("DATA_LIST");
ANALYSISES.DATA_LIST.Columns.Add("ID", System.Type.GetType("System.Int32"));
ANALYSISES.DATA_LIST.Columns.Add("R1", System.Type.GetType("System.Int32"));
ANALYSISES.DATA_LIST.Columns.Add("R2", System.Type.GetType("System.Int32"));
ANALYSISES.DATA_LIST.Columns.Add("R3", System.Type.GetType("System.Int32"));
ANALYSISES.DATA_LIST.Columns.Add("R4", System.Type.GetType("System.Int32"));
ANALYSISES.DATA_LIST.Columns.Add("R5", System.Type.GetType("System.Int32"));
ANALYSISES.DATA_LIST.Columns.Add("TOTAL_BET", System.Type.GetType("System.Decimal"));
string TYPE_NAME = "";
for (int i = 0; i <= 120; i++)
{
TYPE_NAME = "s";
if (i < 10)
{
TYPE_NAME = TYPE_NAME + "00" + i;
}
else if (i > 9 && i < 100)
{
if (i < 75)
{
TYPE_NAME = TYPE_NAME + "0" + i;
}
else if (i == 75)
{
TYPE_NAME = TYPE_NAME + "0741";
}
else
{
TYPE_NAME = TYPE_NAME + "0" + Convert.ToString(i - 1);
}
}
if (i >= 100)
{
if (99 == i - 1)
{
TYPE_NAME = TYPE_NAME + "099";
}
else
{
TYPE_NAME = TYPE_NAME + Convert.ToString(i - 1);
}
}
ANALYSISES.DATA_LIST.Columns.Add(TYPE_NAME, System.Type.GetType("System.Boolean"));
}
int id = 0;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
for (int k = 0; k < 10; k++)
{
for (int m = 0; m < 10; m++)
{
for (int n = 0; n < 10; n++)
{
id++;
DataRow dr = ANALYSISES.DATA_LIST.NewRow();
dr["ID"] = id;
dr["R1"] = i;
dr["R2"] = j;
dr["R3"] = k;
dr["R4"] = m;
dr["R5"] = n;
dr["TOTAL_BET"] = 0;
for (int p = 8; p <= 120; p++)
{
dr[p - 1] = false;
}
ANALYSISES.DATA_LIST.Rows.Add(dr);
}
}
}
}
}
ANALYSISES.DATA_LIST.AcceptChanges();
}

...全文
3046 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 2017-08-07
  • 打赏
  • 举报
回复
引用 23 楼 hailan_li 的回复:
数据库没有内存速度快呀
你怎么知道数据库没有“内存”快? 明明数据库里全部跑完不到1秒, 你用“内存”要几十秒, 摆在眼前的事实还不能说明问题?
hailan_li 2017-08-07
  • 打赏
  • 举报
回复
数据库没有内存速度快呀
dy00544 2017-08-04
  • 打赏
  • 举报
回复
c#是带GC的语言,内存分配和回收都是自动的。 你这种理论上可以将需要更新的数据分成多组,然后每组数据放在一个线程里面处理,有几个组就创建多少个线程。 当然线程数量不要超过服务器逻辑核心的数量。至于如何分组要看你的数据。 另外不知道你数据从哪里读出来的,不明白为啥要先读取到内存表里面更新,直接在数据库里面更新不行么?
hailan_li 2017-08-04
  • 打赏
  • 举报
回复
引用 20 楼 dy00544 的回复:
因为服务器cpu多核心低主频,如果你的程序基本没用到多线程设计,那么这个程序桌面cpu多半会比服务器快得多。
C# 可以自行分配内存吗?像我这样的需求的程序可以设计为多线程去运行吗?
吉普赛的歌 2017-08-03
  • 打赏
  • 举报
回复
写了个完整的,本机测只需要1秒不到(320ms), 你参照着做就是了:
--这里只是测试,你要换成你自己的库
USE tempdb
GO
--1. 创建随机表
IF OBJECT_ID('dbo.random') IS NOT NULL	DROP TABLE dbo.random
IF OBJECT_ID('dbo.targetUpdate') IS NOT NULL	DROP TABLE dbo.targetUpdate
CREATE TABLE dbo.random(id INT PRIMARY KEY)
CREATE TABLE dbo.targetUpdate(id INT PRIMARY KEY, v INT)
--2. 将 10 万条数据顺序插入到随机表
;WITH t1 AS (
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 1000
),t2 AS(
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 100
)
INSERT INTO random(id)
SELECT ROW_NUMBER() OVER (ORDER BY a.number) AS id 
FROM t1 AS a CROSS APPLY t2 AS b
--3. 将 10 万条数据顺序插入到测试的目标表(需要更新的)
INSERT INTO dbo.targetUpdate(id)
SELECT id FROM random

--4. 得到随机的5万条记录,并对应更新目标表中的 5 万条记录
DECLARE @begin DATETIME
SET @begin=GETDATE()
;WITH cte AS(
SELECT TOP 1000000 id FROM random 
WHERE id<=50000
ORDER BY NEWID()
), cte2 AS(
	SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rid,id FROM cte	
)
,tag AS (
	SELECT ROW_NUMBER() OVER(ORDER BY id) AS tid,id,v FROM targetUpdate WHERE id BETWEEN 10001 AND 60000	
)
UPDATE tag 
SET v=cte2.id
FROM cte2
WHERE cte2.rid=tag.tid

SELECT DATEDIFF(ms,@begin,GETDATE()) AS [消耗毫秒数]
/*
消耗毫秒数
320
*/
--查看目标表中已更新过来的记录
SELECT * FROM targetUpdate WHERE id BETWEEN 10001 AND 60000
吉普赛的歌 2017-08-03
  • 打赏
  • 举报
回复
改成用存储过程来跑吧, 不需要什么内存表, 没有阻塞的话2秒钟就可以搞定
吉普赛的歌 2017-08-03
  • 打赏
  • 举报
回复
--这里只是测试,你要换成你自己的库
USE tempdb
GO
--1. 创建随机表
IF OBJECT_ID('dbo.random') IS NOT NULL	DROP TABLE dbo.random
CREATE TABLE dbo.random(id INT PRIMARY KEY)
--2. 将 10 万条数据顺序插入到随机表
;WITH t1 AS (
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 1000
),t2 AS(
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 100
)
INSERT INTO random(id)
SELECT ROW_NUMBER() OVER (ORDER BY a.number) AS id 
FROM t1 AS a CROSS APPLY t2 AS b
--3. 得到随机的2万条记录
;WITH cte AS(
SELECT TOP 1000000 id FROM random 
WHERE id<=20000
ORDER BY NEWID()
)
SELECT ROW_NUMBER()OVER(ORDER BY (select 1)) AS rid,id AS random FROM cte
--你那个表, 直接用上面的结果更新即可
--本机执行, 产生这2万个随机数都不需要一秒
dy00544 2017-08-03
  • 打赏
  • 举报
回复 2
因为服务器cpu多核心低主频,如果你的程序基本没用到多线程设计,那么这个程序桌面cpu多半会比服务器快得多。
吉普赛的歌 2017-08-03
  • 打赏
  • 举报
回复
引用 18 楼 hailan_li 的回复:
[quote=引用 17 楼 yenange 的回复:] 写了个完整的,本机测只需要1秒不到(320ms), 你参照着做就是了:
--这里只是测试,你要换成你自己的库
USE tempdb
GO
--1. 创建随机表
IF OBJECT_ID('dbo.random') IS NOT NULL	DROP TABLE dbo.random
IF OBJECT_ID('dbo.targetUpdate') IS NOT NULL	DROP TABLE dbo.targetUpdate
CREATE TABLE dbo.random(id INT PRIMARY KEY)
CREATE TABLE dbo.targetUpdate(id INT PRIMARY KEY, v INT)
--2. 将 10 万条数据顺序插入到随机表
;WITH t1 AS (
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 1000
),t2 AS(
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 100
)
INSERT INTO random(id)
SELECT ROW_NUMBER() OVER (ORDER BY a.number) AS id 
FROM t1 AS a CROSS APPLY t2 AS b
--3. 将 10 万条数据顺序插入到测试的目标表(需要更新的)
INSERT INTO dbo.targetUpdate(id)
SELECT id FROM random

--4. 得到随机的5万条记录,并对应更新目标表中的 5 万条记录
DECLARE @begin DATETIME
SET @begin=GETDATE()
;WITH cte AS(
SELECT TOP 1000000 id FROM random 
WHERE id<=50000
ORDER BY NEWID()
), cte2 AS(
	SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rid,id FROM cte	
)
,tag AS (
	SELECT ROW_NUMBER() OVER(ORDER BY id) AS tid,id,v FROM targetUpdate WHERE id BETWEEN 10001 AND 60000	
)
UPDATE tag 
SET v=cte2.id
FROM cte2
WHERE cte2.rid=tag.tid

SELECT DATEDIFF(ms,@begin,GETDATE()) AS [消耗毫秒数]
/*
消耗毫秒数
320
*/
--查看目标表中已更新过来的记录
SELECT * FROM targetUpdate WHERE id BETWEEN 10001 AND 60000
强悍,这样确实达到我的目的了,但是我依然不明白为什么高配置服务器性能不如本地台式电脑的一半?[/quote] 可能你的程序没用到并发, 但太厉害的的服务器把你程序试图往并发方面在分配。
hailan_li 2017-08-03
  • 打赏
  • 举报
回复
引用 17 楼 yenange 的回复:
写了个完整的,本机测只需要1秒不到(320ms), 你参照着做就是了:
--这里只是测试,你要换成你自己的库
USE tempdb
GO
--1. 创建随机表
IF OBJECT_ID('dbo.random') IS NOT NULL	DROP TABLE dbo.random
IF OBJECT_ID('dbo.targetUpdate') IS NOT NULL	DROP TABLE dbo.targetUpdate
CREATE TABLE dbo.random(id INT PRIMARY KEY)
CREATE TABLE dbo.targetUpdate(id INT PRIMARY KEY, v INT)
--2. 将 10 万条数据顺序插入到随机表
;WITH t1 AS (
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 1000
),t2 AS(
SELECT sv.number FROM [master].dbo.spt_values AS sv WHERE sv.type='P' AND sv.number BETWEEN 1 AND 100
)
INSERT INTO random(id)
SELECT ROW_NUMBER() OVER (ORDER BY a.number) AS id 
FROM t1 AS a CROSS APPLY t2 AS b
--3. 将 10 万条数据顺序插入到测试的目标表(需要更新的)
INSERT INTO dbo.targetUpdate(id)
SELECT id FROM random

--4. 得到随机的5万条记录,并对应更新目标表中的 5 万条记录
DECLARE @begin DATETIME
SET @begin=GETDATE()
;WITH cte AS(
SELECT TOP 1000000 id FROM random 
WHERE id<=50000
ORDER BY NEWID()
), cte2 AS(
	SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rid,id FROM cte	
)
,tag AS (
	SELECT ROW_NUMBER() OVER(ORDER BY id) AS tid,id,v FROM targetUpdate WHERE id BETWEEN 10001 AND 60000	
)
UPDATE tag 
SET v=cte2.id
FROM cte2
WHERE cte2.rid=tag.tid

SELECT DATEDIFF(ms,@begin,GETDATE()) AS [消耗毫秒数]
/*
消耗毫秒数
320
*/
--查看目标表中已更新过来的记录
SELECT * FROM targetUpdate WHERE id BETWEEN 10001 AND 60000
强悍,这样确实达到我的目的了,但是我依然不明白为什么高配置服务器性能不如本地台式电脑的一半?
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
所有数据都没有到数据库读取,全部在内存中硬塞入,只有每间隔10分钟的数据才通过远程HTTP请求获取,这个过程不到1秒
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
好的,我每一步都统计时间出来看看,看看到底慢在哪个环节,谢谢
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
不是很方便把源代码全部贴上去,我讲一下详细流程: 1、系统服务启动时先初始化创建内存表 2、插入10万条记录到内存表 3、对内存表部分字段进行初始化更新,循环更新的次数大约400万次,条件不同更新的行和列不同 4、系统服务在正常运行的时候,每间隔10分钟会循环更新600万次该内存表,更新的列是同一个列,但更新的条件不同,更新的具体数值也不同,更新的列全部为INT数字整形字段。 实现这样一个业务只有内存表DATATABLE能做到吗?C#还有什么更好的办法能做到我这个业务需求吗? 万分感谢!
引用 9 楼 hanjun0612 的回复:
[quote=引用 7 楼 hailan_li 的回复:] 第一次初始化耗时较长,这个时间我们不算,系统服务在自动化运行的过程中每间隔10分钟会循环更新10万条记录的内存表,合计循环更新操作600多万次,本地重启电脑后运气仍然是 37秒+-,服务器最快就70多秒,服务器配置是我本地电脑的5倍,速度慢了这么多,怎么理解?服务器和发布出去的系统服务要如何设置相关选项?数据也不是到数据库拿的,初始化时候直接塞到内存表,更新的时候也是直接操作内存表。
那你增加stopwatch 在主逻辑里,分别计算耗时,输出到log。 查看哪一步比较耗时, 1 从数据库取数据, 2 装载datatable 看看[/quote]
正怒月神 2017-08-02
  • 打赏
  • 举报
回复
引用 7 楼 hailan_li 的回复:
第一次初始化耗时较长,这个时间我们不算,系统服务在自动化运行的过程中每间隔10分钟会循环更新10万条记录的内存表,合计循环更新操作600多万次,本地重启电脑后运气仍然是 37秒+-,服务器最快就70多秒,服务器配置是我本地电脑的5倍,速度慢了这么多,怎么理解?服务器和发布出去的系统服务要如何设置相关选项?数据也不是到数据库拿的,初始化时候直接塞到内存表,更新的时候也是直接操作内存表。
那你增加stopwatch 在主逻辑里,分别计算耗时,输出到log。 查看哪一步比较耗时, 1 从数据库取数据, 2 装载datatable 看看
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
引用 5 楼 closurer 的回复:
是不是那种虚拟配置的云服务器啊?
坚决不用云服务器,云服务器硬件哪里能得到保证和满足 e7-4830 * 4颗CPU 工业固态SSD 1.9T 磁盘 256 GB内存条,这是服务器配置 本地电脑INTEL 酷睿 I7 内存16GB 非固态磁盘
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
引用 4 楼 hanjun0612 的回复:
你也说内存操作了啊。 如果是服务器,他必须先到数据库去拿,然后放到内存里。 而你本地,内存里已经存在了啊。 你把本地内存清理后测试,看看是不是还是30多秒。
第一次初始化耗时较长,这个时间我们不算,系统服务在自动化运行的过程中每间隔10分钟会循环更新10万条记录的内存表,合计循环更新操作600多万次,本地重启电脑后运气仍然是 37秒+-,服务器最快就70多秒,服务器配置是我本地电脑的5倍,速度慢了这么多,怎么理解?服务器和发布出去的系统服务要如何设置相关选项?数据也不是到数据库拿的,初始化时候直接塞到内存表,更新的时候也是直接操作内存表。
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
[quote=引用 楼主 hailan_li 的回复:] 服务器里面都没有安装,仅安装这个系统服务,是不是服务器需要某些特殊设置,能让这个系统服务大量使用CPU或内存,目前运行情况来看,CPU不到1%,内存也只占用了一点点!特来求解,谢谢!
这说明你的系统设计是比较“死”的顺序程序,不能发挥多核心的能力。[/quote] 依大师你看要如何做?循环600多万次,C#只有内存表DATATABLE才能做到啊,并且我在更新内存表的时候要带查询条件,是服务器上要设置什么吗? 谢谢
闭包客 2017-08-02
  • 打赏
  • 举报
回复
是不是那种虚拟配置的云服务器啊?
正怒月神 2017-08-02
  • 打赏
  • 举报
回复
你也说内存操作了啊。 如果是服务器,他必须先到数据库去拿,然后放到内存里。 而你本地,内存里已经存在了啊。 你把本地内存清理后测试,看看是不是还是30多秒。
hailan_li 2017-08-02
  • 打赏
  • 举报
回复
我知道是十万条记录很快啊,但是我会循环200多次,每次更新3-5万条记录,这样下来几秒钟能搞定吗? 业务需求: for(int i=0;i<220;i++) { DataRow[] dr = DataTable.Select(" where 列=" + i + ""); //这里每次查询的记录量平均3-5万 foreach (DataRow rows in dr) { rows["total"] = rows["total"] + new Random().Next(1, 20000); } } DataTable.AcceptChanges(); 这就是业务需求,耗时都在这个过程当中了
加载更多回复(4)

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧