Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
1

Проект под .NET Framework 2.0 работает на 20% быстрее чем под 4.0

11.04.2015, 18:55. Просмотров 1623. Ответов 16
Метки нет (Все метки)


Добрый день!

Один и тот же проект. Изначально написан под 2.0. В сборке написано Any CPU.

Меняю в сборке на .NET Framework 4.0. Компилирую в релиз - программа работает на 20 - 25% медленней, чем было под 2.0. Если поменять с "Any CPU" на "x86", то скорость возрастает, но все же меньше чем было под 2.0.

Как думаете, с чем это может быть связано?

Добавлено через 5 минут
Тестировал все в релизе не из-под студии.

Добавлено через 31 минуту
Действительно!

На 64-битных системах, если в проекте выставлено "x64" или "AnyCPU", то это дает сильное замедление (20 - 25%) под NET Framework 4.0 и выше. Если же компилировать под x86 или под более низкими фреймфорками (2.0, 3.0, 3.5), то скорость получается выше.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.04.2015, 18:55
Ответы с готовыми решениями:

Как собрать проект под 4.0 Framework если изначально был под 4.5
Есть клиент серверное приложение использующее oledb и стандартные компоненты библиотек, изначально...

Net Framework 4.0 программа под семеркой работает, под XP виснет
Написал софтину, начал тестить. Под семеркой работает как часы, под XP вылетает ошибка "myProg.exe...

Переделать проект под версии Framework ниже 4
Ну похоже достану я тут всех :D , хотя ведь начинать нужно с чего-либо Не пожскажете как мне...

Откомпилировать программу под .Net Framework 2.0
Ребята! Мне очень нужно сделать так что бы программа не требовала не каких особых Фамверков... 2.0...

16
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
12.04.2015, 15:40 2
Suppir, в 4.0 новая среда, и как следствие другой JIT.
0
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
12.04.2015, 15:51  [ТС] 3
Странно, что сборка именно под x64 дает замедление под .NET Framework 4.0 и выше.

Должно быть, это какая-то ошибка Microsoft.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
12.04.2015, 16:39 4
Suppir, x64 компилятор быстрее x86, а .net 4.0 джиты лучше, чем в 2.0. Но это не значит, что для любой программы x64 > x86, а .Net 4.0 > .Net 2.0

Добавлено через 6 минут
Например попробуй такой код работает на ~400% быстрее под .Net 4.0 x64
C#
1
2
3
4
5
6
7
8
9
10
11
12
    class Program
    {
        static void Main(string[] args)
        {
            int sum = 0;
            for (int i = 0; i < 1024; i++)
            {
                sum += i;
            }
            Console.WriteLine("Sum = {0}", sum);
        }
    }
Добавлено через 6 минут
А такой
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Diagnostics;
 
namespace ConsoleApplication40
{
    class Program
    {
        static void Main(string[] args)
        {
            var sw = Stopwatch.StartNew();
            int trash = 0;
            for (int j = 0; j < 100000000; j++)
            {
                int sum = 0;
                for (int i = 0; i < 4; i++)
                {
                    sum += i;
                }
                trash += sum;
            }
            sw.Stop();
            Console.WriteLine("Sum = {0}\tElapsed = {1}", trash, sw.ElapsedTicks);
        }
    }
}
Будет работать в ~3 раза быстрее, тупо от переключения x86 на х64 (под .Net 4.0)
1
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
13.04.2015, 16:05  [ТС] 5
Psilon,

Мне бы еще понять, как переписать программу, чтобы она быстрее работала под 4.0. Пока что работает явно медленней. Пришлось обратно на 2.0 откатиться.
Можно было поставить 3.5, но это полумера, поскольку хотел использовать таски, а линк не особо нужен.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.04.2015, 16:09 6
Suppir,
1) косяк в коде - не используются оптимизации JITа.
2) если человек говорит, что ему не нужен linq - то он не знает шарпа По крайней мере полвины точно
0
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
13.04.2015, 16:18  [ТС] 7
Под x86
Цитата Сообщение от Psilon Посмотреть сообщение
1) косяк в коде - не используются оптимизации JITа.
А как использовать оптимизации Jit'а в коде? Можно какой-то пример?

Насчет Linq - ну, как известно, это просто высокоуровневая обертка. То есть те же запросы можно и обычными условиями написать. Конечно, если запрос длинный и сложный, разные там объединения таблиц, то проще линком будет.

Насчет знаний - ну, я знаю в рамках потребностей. Например, нужна была многопоточность - посидел, разобрался (с вашей помощью). А прямо все-все знать невозможно. В планах изучить линк, плинк и таски и постепенно вставлять в свои программы.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.04.2015, 16:23 8
Цитата Сообщение от Suppir Посмотреть сообщение
А как использовать оптимизации Jit'а в коде? Можно какой-то пример?
C#
1
2
3
4
5
6
7
8
9
10
11
        static void Main()
        {
            var sw = Stopwatch.StartNew();
            int sum = 0;
            for (int i = 0; i < 1000000001; i++)
            {
                sum += i;
            }
            sw.Stop();
            Console.WriteLine("{0} - {1}", sum, sw.ElapsedMilliseconds);
        }
ставим x64 release и собираем компилируем (.net 4.0+ лучше поставить). Запоминаем результат, меняем 1000000001 на 1000000000 и запускаем еще раз.

Цитата Сообщение от Suppir Посмотреть сообщение
Насчет Linq - ну, как известно, это просто высокоуровневая обертка. То есть те же запросы можно и обычными условиями написать. Конечно, если запрос длинный и сложный, разные там объединения таблиц, то проще линком будет.
а ООП это лишь обертка над фон-неймовской архитектурой, которая сама лишь обертка над машиной Тьюринга, следовательно шарп не нужен, то же самое можно добиться и обычными перемещениями головки конечного автомата
0
Эксперт .NETАвтор FAQ
9834 / 4794 / 1725
Регистрация: 11.01.2015
Сообщений: 5,973
Записей в блоге: 34
13.04.2015, 17:34 9
Цитата Сообщение от Suppir Посмотреть сообщение
сборка именно под x64 дает замедление
Regex используется? Параметр RegexOptions.Compiled есть ?
0
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
13.04.2015, 17:50  [ТС] 10
Storm23,

Используется дофига регексов. Они все прекомпилированные, объявлены в начале программы, а используются из других потоков.
Я пробовал их объявлять внутри метода, который запускается в отдельном потоке, но тогда работает еще медленней.

Добавлено через 44 секунды
Нашел вот такой текст по оптимизации JIT:

've actually did quite a bit of research on optimizing C# code. So far, these are the most significant results:

Func's and Action's that are passed directly are often inlined by the JIT'ter. Note that you shouldn't store them as variable, because they are then called as delegates. See also this post for more details.

Be careful with overloads. Calling Equals without using IEquatable<T> is usually a bad plan - so if you use f.ex. a hash, be sure to implement the right overloads and interfaces, because it'll safe you a ton of performance.

Generics called from other classes are never inlined. The reason for this is the "magic" outlined here.

If you use a data structure, make sure to try using an array instead :-) Really, these things are fast as hell compared to ... well, just about anything I suppose. I've optimized quite a bit of things by using my own hash tables and using arrays instead of list's.

In a lot of cases, table lookups are faster than computing things or using constructions like vtable lookups, switches, multiple if statements and even calculations. This is also a good trick if you have branches; failed branch prediction can often become a big pain. See also this post - this is a trick I use quite a lot in C# and it works great in a lot of cases. Oh, and lookup tables are arrays of course.

Experiment with making (small) classes structs. Because of the nature of value types, some optimizations are different for struct's than for class'es. For example, method calls are simpler, because the compiler knows exactly what method is going to get called. Also arrays of structs are usually faster than arrays of classes, because they require 1 memory operation less per array operation.

Don't use multi-dimensional arrays. While I prefer Foo[], even Foo[][] is normally faster than Foo[,].

If you're copying data, prefer Buffer.BlockCopy over Array.Copy any day of the week. Also be cautious around strings: string operations can be a performance drainer.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.04.2015, 18:13 11
Suppir, а вот это вредные советы. Например Array.Copy от Buffer.BlockCopy отличается по производительности в тысячные доли процента, на уровне погрешности. Разве что про Equals написанно толково.
0
Эксперт .NETАвтор FAQ
9834 / 4794 / 1725
Регистрация: 11.01.2015
Сообщений: 5,973
Записей в блоге: 34
13.04.2015, 18:23 12
Цитата Сообщение от Suppir Посмотреть сообщение
Используется дофига регексов. Они все прекомпилированные, объявлены в начале программы, а используются из других потоков.
Тогда понятно почему тормозит на x64. Это известный глюк - тормоза RegexOptions.Compiled под x64.
Решается отключением этой опции, если текущая архитектура машины x64.

Почитать про глюк можно например здесь ну или в гугле "x64 Compiled Regex bug"
1
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
13.04.2015, 19:25  [ТС] 13
Цитата Сообщение от Storm23 Посмотреть сообщение
Тогда понятно почему тормозит на x64. Это известный глюк - тормоза RegexOptions.Compiled под x64.
Спасибо, попробую. У меня 70 регексов только в начале программы объявлены. И еще пара десятков внутри методов.

Добавлено через 7 минут
Попробовал - нет, не в этом дело.

Сборка 4.0, x64.
Прекомпилированные регексы - 71,3 Мб/секунду
Просто регексы - 70,6 Мб/секунду

Добавлено через 3 минуты
Сборка 2.0, AnyCPU
Прекомпилированные регексы - 97,1 Мб/сек
Просто регексы - 93,3 Мб/сек.

Добавлено через 8 минут
Сборка 2.0, x64 - скорость аналогична Сборка 2.0, AnyCPU (под сотню Мб/сек).

Добавлено через 4 минуты
Цитата Сообщение от Suppir Посмотреть сообщение
Generics called from other classes are never inlined
А вот как это перевести, кто объяснит суть?
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.04.2015, 19:32 14
Suppir, Generic-функции не инлайнятся. Как правило это не проблема, потому что генерики редко однострочные.

Добавлено через 3 минуты
Хотя ни одного подтверждения в инете я так и не нагуглил

Добавлено через 2 минуты
если конечно не считать пост-источник на SO
0
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
14.04.2015, 21:03  [ТС] 15
Добавлено через 21 секунду
Цитата Сообщение от Psilon Посмотреть сообщение
Будет работать в ~3 раза быстрее, тупо от переключения x86 на х64 (под .Net 4.0)
Потестировал - у меня что-то код работает с одинаковой скоростью в 4.0 в x64 и x86.
Запускал release не из под студии. Сама студия - 2013.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
14.04.2015, 21:43 16
Ну значит с настройками чудите.
0
Миниатюры
Проект под .NET Framework 2.0 работает на 20% быстрее чем под 4.0  
25 / 25 / 10
Регистрация: 08.08.2011
Сообщений: 1,160
14.04.2015, 21:49  [ТС] 17
Вот этот код использовал:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Diagnostics;
 
namespace ConsoleApplication40
{
    class Program
    {
        static void Main(string[] args)
        {
            var sw = Stopwatch.StartNew();
            int trash = 0;
            for (int j = 0; j < 100000000; j++)
            {
                int sum = 0;
                for (int i = 0; i < 4; i++)
                {
                    sum += i;
                }
                trash += sum;
            }
            sw.Stop();
            Console.WriteLine("Sum = {0}\tElapsed = {1}", trash, sw.ElapsedTicks);
        }
    }
}
Две сборки сделал: x86 и x64 (NET 4.0). Запустил release из-под total commander. Разницы в скорости практически нет
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.04.2015, 21:49

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Как запустить .NET Framework под wine?
Нашел на одном форуме эту ссылку http://appdb.winehq.org/appview.php?iAppId=2586 Качаю, после...

Как скомпилировать программу на c# под .net Framework 3.5 и выше?
Написал программу. Если компилирую по 3,5 Framework, то не идет на 4,5, если на 4,5, то на 3,5 не...

Как определить под какой .NET Framework написана dll?
Всем добрый день, Я использую вот эту библиотеку http://www.itinvest.ru/software/smartcom/...

Где найти/как установить net framework 2 под windows 7
История такая есть новый комп за которым будет работать чел, с этого компа будут отправляться...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.