Си. Преобразование из массива char в int.

 
1 2 3 4 5
RU GOGI #24.01.2012 07:47  @Татарин#24.01.2012 06:04
+
-
edit
 

GOGI

координатор
★★★★
Татарин> Стоп. А зачем его целиком копировать в другой?
Потому что напрямую работать с этим массивом, как свойством класса, очень долго. См. ответ Сергею
1  
RU GOGI #24.01.2012 07:54  @Сергей-4030#24.01.2012 06:06
+
-
edit
 

GOGI

координатор
★★★★
Сергей-4030> Почему? Что-то не совсем понятно... ты выделяешь массив. Что значит "ужасно медленное" обращение? И почему если его скопировать в другой, то будет быстрее? Что поменялось?
Вот смотри, есть класс SomeClass и его свойство SomeArray() as Double()
Если я напрямую беру и в цикле For (в другом модуле) сравниваю все его элементы с одним числом, это занимает, к примеру, секунд 7. Если я сначала скопирую весь массив SomeArray в TempArray, и потом уже его прогоню в For, это занимает около 30 мс. Почему так вопрос не ко мне, а к .Net. Внутри класса все работает быстро. Майкрософт рекомендует в качестве свойства использовать список, а не массив, но у меня сомнения, что это как-то убыстрит процесс.
1  

GOGI

координатор
★★★★
AXT> Не понял. Делегаты запрещены, или что?
Нет, просто надо чтобы вся работа в классе обработки велась в процедурах, а не функциях. Для дальнейшего удобства. Можно вернуть функцией, но копировать во временный массив пока проще
1  
EE Татарин #24.01.2012 08:07  @GOGI#24.01.2012 07:47
+
-
edit
 

Татарин

координатор
★★★★☆
Татарин>> Стоп. А зачем его целиком копировать в другой?
GOGI> Потому что напрямую работать с этим массивом, как свойством класса, очень долго. См. ответ Сергею
Всё-таки приведи конкретный код, как сделано свойство?
Детали имеют значение.

Тут всё зависит от того, нафига тебе свойство, то есть, причины, по которым ты скрыл массив от внешних сил.

Может, тебя бы устроило просто
public int[] m_someArray;
?
...А неубитые медведи делили чьи-то шкуры с шумом. Боюсь, мы поздно осознали, к чему всё это приведёт.  16.0.912.7516.0.912.75
RU Balancer #24.01.2012 08:20  @Татарин#24.01.2012 06:31
+
-
edit
 

Balancer

администратор
★★★★★
Татарин> Большинство больших проектов сейчас начинаются на языках со сборщиком мусора.

Более того, сборку мусора начинают вводить в Си++ :) C++11 уже определяются возможные реализации для этого.
 
RU GOGI #24.01.2012 08:31  @Татарин#24.01.2012 08:07
+
-
edit
 

GOGI

координатор
★★★★
Татарин> Может, тебя бы устроило просто
Татарин> public int[] m_someArray;
Меня бы в общем-то устроило, но скорости это не повышает.
1  
EE Татарин #24.01.2012 08:39  @GOGI#24.01.2012 08:31
+
-
edit
 

Татарин

координатор
★★★★☆
Татарин>> public int[] m_someArray;
GOGI> Меня бы в общем-то устроило, но скорости это не повышает.
Эээ... позвольте, однако ж, добрый сэр, Вас спросить: а в сравнении с чем? :)

Это прямой доступ к данным класса. Что может быть быстрее в принципе?
...А неубитые медведи делили чьи-то шкуры с шумом. Боюсь, мы поздно осознали, к чему всё это приведёт.  16.0.912.7516.0.912.75
PL GOGI #24.01.2012 08:43  @Татарин#24.01.2012 08:39
+
-
edit
 

GOGI

координатор
★★★★
Татарин> Эээ... позвольте, однако ж, добрый сэр, Вас спросить: а в сравнении с чем? :)
Пишу же, копирование массива во временный и выполнение всех операций с ним дает ускорение в несколько порядков. Насколько я могу представить, как не специалист получение что одного элемента, что всего массива из класса одномоментно занимает примерно одинаковое время, достаточно большое.
1  
US Сергей-4030 #24.01.2012 09:22  @GOGI#24.01.2012 08:43
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Татарин>> Эээ... позвольте, однако ж, добрый сэр, Вас спросить: а в сравнении с чем? :)
GOGI> Пишу же, копирование массива во временный и выполнение всех операций с ним дает ускорение в несколько порядков. Насколько я могу представить, как не специалист получение что одного элемента, что всего массива из класса одномоментно занимает примерно одинаковое время, достаточно большое.

Не думаю. Скорее .net делает вызов функции для каждого вызова:

for(int i=0;i<Big.getArray().length();i++)
if(Big.getArray()[i]==5)
return true;

Тут, во-первых, нужно вот что проверить - точно ли тебе нужен массив, а не map. Во-вторых - вероятно, .Net вызывает функцию на каждом проходе цикла. Может тебе перенести параметры поближе к массиву? Вызывать так:

if(Big.findInArray(5))
return true;

А findInArray будет такой:


for(int i=0;i<array.length();i++)
if(array[i]==5)
return true;
 16.0.912.7516.0.912.75

GOGI

координатор
★★★★
Как показали натурные эксперименты, скорость доступа к массиву низкая, если применять позднее связывание класса, но применять раннее я не могу, так как класс компилируется из исходника во время работы программы.
1  
RU GOGI #24.01.2012 09:27  @Сергей-4030#24.01.2012 09:22
+
-
edit
 

GOGI

координатор
★★★★
Сергей-4030> Тут, во-первых, нужно вот что проверить - точно ли тебе нужен массив, а не map.
Я электрик, а не программист, я даже не знаю, что такое map и Гугл сходу мне не помог.
>Может тебе перенести параметры поближе к массиву?
У меня и так все что можно, внутри класса, тут просто идет взаимодействие с формой. Теоретически, я конечно могу и его перенести в класс, но пока временный массив проще.
1  
EE Татарин #24.01.2012 09:28  @GOGI#24.01.2012 08:43
+
-
edit
 

Татарин

координатор
★★★★☆
Татарин>> Эээ... позвольте, однако ж, добрый сэр, Вас спросить: а в сравнении с чем? :)
GOGI> Пишу же, копирование массива во временный и выполнение всех операций с ним дает ускорение в несколько порядков. Насколько я могу представить, как не специалист получение что одного элемента, что всего массива из класса одномоментно занимает примерно одинаковое время, достаточно большое.
Нет, что-то тут не так. Вот просто работа с таким массивом (как я выше написал) - и есть максимально быстрое из возможного. Там нечего ускорять в принципе, это не свойство, нет посредников. Это тупо данные, член класса. Если ты утверждаешь, что у тебя вдруг такая конструкция работает на порядки аж медленнее, чем некий "временный" массив (чем он отличается-то?), то у меня достаточно своего опыта, чтоб попервой предположить, что ты что-то напутал.

О чём я говорю?

code text
  1. class SomeClass
  2. {
  3. public int[] m_someArray;
  4. public SomeClass(){m_someArray = new int[1000000];}
  5. };
  6.  
  7. void SomeShitHappens()
  8. {
  9. SomeClass sc;
  10. for(int i = 0;;)sc.m_someArray[i++] = 0;
  11. }

Я утверждаю, что этот код будет вылетать в дебаггер через ровно такое же время, как и
code text
  1. void SomeShitHappens()
  2. {
  3. int []someArray = new int[10000000];
  4. for(int i = 0;;)someArray[i++] = 0;
  5. }


Приведи конкретный код, который у тебя работает медленно.
Иначе понять тебя реально сложно.
...А неубитые медведи делили чьи-то шкуры с шумом. Боюсь, мы поздно осознали, к чему всё это приведёт.  16.0.912.7516.0.912.75

GOGI

координатор
★★★★
Ну вот пример
code text
  1. Module Module1
  2.     Dim TestClass = New Test
  3.     Sub Main()
  4.         Dim StartTick = My.Computer.Clock.TickCount
  5.         For i = 0 To TestClass.testarray.GetUpperBound(0)
  6.             TestClass.testarray(i) = Rnd()
  7.         Next
  8.         Debug.Print(My.Computer.Clock.TickCount - StartTick)
  9.     End Sub
  10. End Module
  11.  
  12. Public Class Test
  13.     Public TestArray(1000000) As Double
  14. End Class

Выполняется 10562 мс

code text
  1. Module Module1
  2.     Dim TestClass = New Test
  3.     Dim TestArray1(1000000) As Double
  4.     Sub Main()
  5.         TestArray1 = TestClass.testarray
  6.         Dim StartTick = My.Computer.Clock.TickCount
  7.         For i = 0 To TestArray1.GetUpperBound(0)
  8.             TestArray1(i) = Rnd()
  9.         Next
  10.         Debug.Print(My.Computer.Clock.TickCount - StartTick)
  11.     End Sub
  12. End Module
  13. Public Class Test
  14.     Public TestArray(1000000) As Double
  15. End Class

выполняется 63 мс

P.S. связывание не причем, это я прогнал. Но влияет где объявлять переменную, которой присваивается класс, если на уровне модуля, то долго, если на уровне процедуры, то быстро
1  
+
-
edit
 

arkhnchul

втянувшийся

code text
  1. Module Module1
  2.         Dim TestClass = New Test
  3.         Sub Main()
  4.             Dim StartTick = My.Computer.Clock.TickCount
  5.             For i = 0 To TestClass.testarray.GetUpperBound(0)
  6.                 TestClass.testarray(i) = Rnd()
  7.             Next
  8.             Debug.Print(My.Computer.Clock.TickCount - StartTick)
  9.         End Sub
  10.     End Module
  11.      
  12.     Public Class Test
  13.         Public TestArray(1000000) As Double
  14.     End Class


может, я не так вникаю в сей язык и как оно внутри там работает, но, судя по моему скромному опыту других языков и понимания асма:
1) на каждом проходе цикла он дергает GetUpperBound - это лишние call-ы.
2) на каждом проходе цикла он два раза обращается к свойству класса Test - также call-ы на оно самое и на проверку прав доступа к свойству.

т.е. я бы писал что-то вроде:
code text
  1. Module Module1
  2.         Dim TestClass = New Test
  3.         Sub Main()
  4.             Dim StartTick = My.Computer.Clock.TickCount
  5.             Dim myArray=TestClass.testarray;
  6.             Integer upperBound=myArray.GetUpperBound(0);
  7.  
  8.             For i = 0 To upperBound
  9.                 myArray(i) = Rnd()
  10.             Next
  11.             Debug.Print(My.Computer.Clock.TickCount - StartTick)
  12.         End Sub
  13.     End Module
  14.      
  15.     Public Class Test
  16.         Public TestArray(1000000) As Double
  17.     End Class
тут допущение, что "Dim myArray=TestClass.testarray" пройдет как создание ссылки, а не копирования всего экземпляра.
 9.0.19.0.1
+
-1
-
edit
 

digger

аксакал

tarasv> Как человек праралельно писавший проекты на C++ и Java могу сказать IDE для С++ чудовищно убоги по сравнению с современными java-скими

Фичей у Эклипса да больше,но работает оно как-то криво.Постоянно не реагирует на кнопки, ошибки компиляции не выводятся на строку сорса, брейкпойнты не работают, перегрузка после перекомпиляции с трудом итп.
 3.6.83.6.8
US Сергей-4030 #24.01.2012 22:04  @GOGI#24.01.2012 09:42
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
GOGI> Ну вот пример
GOGI> выполняется 63 мс
GOGI> P.S. связывание не причем, это я прогнал. Но влияет где объявлять переменную, которой присваивается класс, если на уровне модуля, то долго, если на уровне процедуры, то быстро

Надо думать, компилятор не может провести оптимизацию доступа к массиву и вместо прямого доступа, каждый раз вызывает функцию. В любом случае, так как ты делаешь - не совсем правильно. Ты должен делать так:

code text
  1. Module Module1
  2.     Dim TestClass = New Test
  3.     Sub Main()
  4.         Dim StartTick = My.Computer.Clock.TickCount
  5.         TestClass.initializaWithRandom();
  6.         Debug.Print(My.Computer.Clock.TickCount - StartTick)
  7.     End Sub
  8. End Module
  9.  
  10. Public Class Test
  11.     TestArray(1000000) As Double
  12.    
  13.     Sub initializeWithRandom()
  14.         For i = 0 To TestArray.GetUpperBound(0)
  15.             TestArray(i) = Rnd()
  16.         Next
  17.     End Sub
  18. End Class
 16.0.912.7516.0.912.75
+
-1
-
edit
 

digger

аксакал

Опять потому что скрипт и программист не контролирует что он пишет.На С если это просто массив в памяти, это действительно массив в памяти и обращение к нему по пойнтеру,тормозить он может только если кэш тормозит. Если это класс - то обращание к нему как программист написал.В скриптах это классы, инкапсулированные самим языком и написать просто массив в нормальной памяти вообще невозможно, хоть ее у тебя терабайт.На огромный я бы делал memory mapped file,а то и вообще класс с рукопашный свопом в файлах и кэшем, приходилось сортировать здоровенный кусок данных.

Про пойнтеры.Пойнтер ,где они есть, - это фактически оффсет в массиве.Начиная с корневого поста, в языке с таковыми можно прочитать бутсектор в буффер, в буффере прочитать любое значение с любого оффсета или прилепить туда пойнтер на структуру.Машинная независимость гарантирует,что порядок байтов и оффсет каждого члена структуры не поменяются.
 3.6.83.6.8
US Сергей-4030 #24.01.2012 22:07  @digger#24.01.2012 21:50
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
digger> Фичей у Эклипса да больше,но работает оно как-то криво.Постоянно не реагирует на кнопки, ошибки компиляции не выводятся на строку сорса, брейкпойнты не работают, перегрузка после перекомпиляции с трудом итп.

Гы, мастера видно издалека. :lol:

PS Впрочем, я думаю, я знаю, что происходит. Диггер пользует какой-нибудь плагин-эмулятор андроидного телефона. И косяки этого эмулятора приписывает Эклипсу.
 16.0.912.7516.0.912.75
US Сергей-4030 #24.01.2012 22:09  @digger#24.01.2012 22:06
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
digger> Опять потому что скрипт и программист не контролирует что он пишет.На С если это просто массив в памяти, это действительно массив в памяти и обращение к нему по пойнтеру,тормозить он может только если кэш тормозит. Если это класс - то обращание к нему как программист написал.В скриптах это классы, инкапсулированные самим языком и написать просто массив в нормальной памяти

Вы, товарищ, дурак, извините. Не примите за оскорбление.
 16.0.912.7516.0.912.75

tarasv

опытный

digger> Фичей у Эклипса да больше,но работает оно как-то криво.Постоянно не реагирует на кнопки, ошибки компиляции не выводятся на строку сорса, брейкпойнты не работают, перегрузка после перекомпиляции с трудом итп.

Ну так если не нравится Эклипс (он мне то-же не нравится) то если IntelliJ IDEA. На кнопки реагирует, с брекпоинтами и ошибками компиляции проблем нет. Перегузка после перекомпиляции это уже к jvm - изменить интерфес уже загруженного класса на ходу она не дает, реализации методов заменяются без проблем. Достаточно удобно интегрирована через плагины с кучей фреймворков, version control и т.д. Минусы - не бесплатная и местами с совершенно сумашедшими клавишными шорткатами. Поддержка Андроида есть, насколько качественная, не знаю, не проверял.
 3.6.253.6.25
Это сообщение редактировалось 24.01.2012 в 22:36
+
-
edit
 

Mishka

модератор
★★★

arkhnchul> 1) на каждом проходе цикла он дергает GetUpperBound - это лишние call-ы.
arkhnchul> 2) на каждом проходе цикла он два раза обращается к свойству класса Test - также call-ы на оно самое и на проверку прав доступа к свойству.

Совершенно верно.


arkhnchul> тут допущение, что "Dim myArray=TestClass.testarray" пройдет как создание ссылки, а не копирования всего экземпляра.

Да, тут, вроде, как в Джаве. Не копируется весь массив, а только ссылка.
 7.0.17.0.1
US Mishka #24.01.2012 23:00  @Сергей-4030#24.01.2012 22:04
+
-
edit
 

Mishka

модератор
★★★

Сергей-4030> Надо думать, компилятор не может провести оптимизацию доступа к массиву и вместо прямого доступа, каждый раз вызывает функцию. В любом случае, так как ты делаешь - не совсем правильно. Ты должен делать так:
Ну, если хочеться использовать алгоритмы разные (sort, find, etc), то туда надо всё равно надо будет, как ссылку на массив. Все возможные операции в класс не запихнуть. В этом случае, передача объекта по ссылке вполне решение.
 7.0.17.0.1

tarasv

опытный

arkhnchul>> 1) на каждом проходе цикла он дергает GetUpperBound - это лишние call-ы.
arkhnchul>> 2) на каждом проходе цикла он два раза обращается к свойству класса Test - также call-ы на оно самое и на проверку прав доступа к свойству.
Mishka> Совершенно верно.

Там скорее проблема с динамической типизацией. Объявление Dim TestArray1(1000000) As Double дает выйгрыш больше чем на порядок, а при объявлении Dim TestArray1 = TestClass.TestArray выйгрыш в пару-тройку раз. В ассемблерном коде разница заметна очень сильно - первый вариант 24 инструкции и 3 вызова процедур второй 35 и 7 вызовов и исходный с обращением к полю класса 42 инструкции и 7 вызовов.
 3.6.253.6.25

Mishka

модератор
★★★

tarasv> Там скорее проблема с динамической типизацией. Объявление Dim TestArray1(1000000) As Double дает выйгрыш больше чем на порядок, а при объявлении Dim TestArray1 = TestClass.TestArray выйгрыш в пару-тройку раз. В ассемблерном коде разница заметна очень сильно - первый вариант 24 инструкции и 3 вызова процедур второй 35 и 7 вызовов и исходный с обращением к полю класса 42 инструкции и 7 вызовов.

Слушай, а попробуй, как
Dim TestArray () As Double
TestArray = TestClass.TestArray

Ну и потом в цикл.

PS У меня под рукой нет VB.Net
 7.0.17.0.1

tarasv

опытный

Mishka> Слушай, а попробуй, как

Естественно что все стало наилучшим образом, вместе с убиранием обращения к размеру массива каждый раз в цикле стало 31мс, а в исходном варианте на моей машине было ~8 сек.

code text
  1. Module Module1
  2.     Dim TestClass = New Test
  3.     Sub Main()
  4.         Dim StartTick = My.Computer.Clock.TickCount
  5.         Dim TestArray1() As Double = TestClass.TestArray
  6.         Dim count As Integer = TestClass.TestArray.GetUpperBound(0)
  7.         For i = 0 To count
  8.             TestArray1(i) = Rnd()
  9.         Next
  10.         Debug.Print(My.Computer.Clock.TickCount - StartTick)
  11.     End Sub
  12. End Module
  13.  
  14. Public Class Test
  15.     Public TestArray(1000000) As Double
  16. End Class
 3.6.253.6.25
1 2 3 4 5

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru